digitalmars.D - Function calls
- bearophile (36/36) Jan 26 2010 I have written the following closure, to generate numbers in 1-7 from nu...
- Bernard Helyer (2/6) Jan 27 2010 Nothing to add except a voice of support.
- Lars T. Kyllingstad (4/50) Jan 27 2010 I thought that this issue had been settled a long time ago, and that
- Michel Fortin (8/10) Jan 27 2010 It's just not fully implemented yet. The @property attribute is there,
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (8/44) Jan 27 2010 I disagree, I find the function calls without the () to be really
- Adam D. Ruppe (5/15) Jan 27 2010 Me too.
- downs (2/16) Jan 27 2010 Me three.
- Michel Fortin (8/15) Jan 27 2010 I'll miss the feature too. But I think it's the right thing to do
- boscop (7/21) Jan 27 2010 It may be optically pleasant sometimes to be able to omit the parens,
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (3/24) Jan 27 2010 I think you're looking for a profiler. I also disagree about the
- Nick Sabalausky (5/21) Jan 27 2010 Meh, I hate it hate it hate it hate it hate it. I'd dance on the feature...
- Denis Koroskin (3/26) Jan 27 2010 Me too!
- Andrei Alexandrescu (11/27) Jan 27 2010 There was a long discussion about that, which prompted the addition of
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (3/30) Jan 27 2010 Not just parameterless functions, but functions operating on arrays as
- Michel Fortin (20/24) Jan 27 2010 Well, perhaps it'd be better if it was 'property' instead of
- Craig Black (9/29) Jan 27 2010 Yes, agreed, there should be some more thought put into how keywords wor...
- Lars T. Kyllingstad (7/31) Jan 28 2010 This was actually discussed before, and I think the general conclusion
- Steven Schveighoffer (15/40) Jan 28 2010 1. Choosing between including @property or not is rare. Most cases are ...
- Andrei Alexandrescu (9/22) Jan 28 2010 I need to put it for all front() and empty() declarations. By the way I
- Lars T. Kyllingstad (10/17) Jan 28 2010 Because it's an action, not a property. Simple as that. :)
- Steven Schveighoffer (27/48) Jan 28 2010 Because popFront isn't a property. It doesn't return anything, does it?...
- Leandro Lucarella (7/15) Jan 28 2010 Because it denotes an action?
- Adam D. Ruppe (10/15) Jan 28 2010 I don't think it is that simple - I see popFront; as an action all the
- Steven Schveighoffer (12/20) Jan 28 2010 Whether you use parentheses or not, it's not a property. The statement ...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (6/27) Jan 28 2010 I do not understand why this is damage at all. It's like collateral
- Lars T. Kyllingstad (6/27) Jan 28 2010 ...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(),
- Denis Koroskin (3/28) Jan 28 2010 Great explanation, very convincing!
- Andrei Alexandrescu (7/39) Jan 28 2010 How about this:
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (4/43) Jan 28 2010 I say you don't, it works both ways as it is now. I say, let's not
- Don (11/64) Jan 28 2010 I think there are 3 cases:
- Andrei Alexandrescu (22/35) Jan 28 2010 Good summary. I now wonder, could one overload based on @property?
- Andrei Alexandrescu (5/37) Jan 28 2010 I was mistaken. byLine does fetch a range.
- Nick Sabalausky (14/31) Jan 28 2010 Why would that ever enter into anyone's mind? You already can't overload...
- Andrei Alexandrescu (4/44) Jan 28 2010 Nonono, the expression "tail wagging the dog" means that the actual tail...
- Steven Schveighoffer (4/42) Jan 28 2010 byLine is a property. It is fetching a range on stdin.
- Andrei Alexandrescu (3/16) Jan 28 2010 Damn. I was sure the answer will be different.
- Bill Baxter (12/29) Jan 28 2010 Maybe "property" is a misleading word. Clearly there are more things
- Andrei Alexandrescu (3/30) Jan 28 2010 This raises the hair on my back. It's back to programming-by-convention.
- Bill Baxter (7/42) Jan 28 2010 Wait, you started off by saying "how do I decide?" and we give you a
- Andrei Alexandrescu (3/38) Jan 28 2010 It's not a rule. It's several contradictory ones.
- Bill Baxter (8/55) Jan 28 2010 s
- Andrei Alexandrescu (5/45) Jan 28 2010 Some said it should be stdin.byLine(), some others said it should be
- Bill Baxter (15/74) Jan 28 2010 ngs
- Gerrit Wichert (97/98) Jan 29 2010 Hello,
- Michel Fortin (24/43) Jan 29 2010 Objective-C properties look like that too. You declare a property with
- Michiel Helvensteijn (13/26) Jan 28 2010 byLine() is a function. It changes the state of stdin. Calling it
- Bill Baxter (7/25) Jan 28 2010 d
- Michiel Helvensteijn (5/13) Jan 28 2010 Ah, my bad. I was guessing. Still, returning a handle from a property th...
- Andrei Alexandrescu (4/16) Jan 28 2010 I agree. So where's the consensus? Things seemed so clear when people
- Bill Baxter (7/25) Jan 28 2010 I really don't see what the problem is there.
- Andrei Alexandrescu (4/26) Jan 28 2010 The problem is not localized change. The result of stdin.byLine changes
- Bill Baxter (8/41) Jan 28 2010 Ok, so you have no problem with a car.wheels returning a mutable wheels ...
- Andrei Alexandrescu (4/38) Jan 28 2010 If you access car.wheel, it is reasonable to repaint that wheel. The
- Nick Sabalausky (15/30) Jan 28 2010 Ok, so you don't think a property of something should be able to change
- Bill Baxter (14/46) Jan 28 2010 m
- Nick Sabalausky (10/54) Jan 28 2010 I assume you meant "no-argument function".
- Andrei Alexandrescu (3/56) Jan 28 2010 Because a function doesn't attempt to emulate a field.
- Nick Sabalausky (3/14) Jan 28 2010 D's approach to properties *forces* functions to emulate fields.
- Andrei Alexandrescu (4/19) Jan 28 2010 Unfortunately not. It forces nothing. That's my problem with the feature...
- Nick Sabalausky (15/33) Jan 28 2010 A programming language *is* a set of enforced conventions. When somethin...
- Nick Sabalausky (7/43) Jan 28 2010 We can keep dancing around it with different evidence, metaphors and
- Justin Johansson (6/50) Jan 29 2010 Creeping elegance is the root of all evil.***
- Jesse Phillips (9/22) Jan 28 2010 I agree. If we do not require parentheses on functions then there is no
- Steven Schveighoffer (17/34) Jan 29 2010 It forces a convention. The convention is important, almost as importan...
- Andrei Alexandrescu (4/27) Jan 29 2010 It forces you to define a convention as vacuous and open to
- Rainer Deyke (8/14) Jan 29 2010 Not really relevant, since the same applies to fields.
- Michel Fortin (43/45) Jan 28 2010 No. Calling byLine doesn't change the stream. It returns a different
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (2/7) Jan 29 2010 It reads a line off stdin. Try it.
- Michel Fortin (17/27) Jan 29 2010 Ah, I see, you're right. Silly me for not trying.
- Steven Schveighoffer (9/30) Jan 29 2010 Hey, it's that dead horse again, let's beat it!
- Michel Fortin (28/35) Jan 29 2010 Andrei is the one who complained that it's difficult to know whether
- Steven Schveighoffer (7/37) Jan 29 2010 I agree.
- Andrei Alexandrescu (17/30) Jan 29 2010 I'll tell you what I'd have liked: a landslide of responses to my
- Steven Schveighoffer (24/53) Jan 29 2010 It's been mentioned before that tough decisions need to be made in many ...
- Andrei Alexandrescu (3/27) Jan 29 2010 Except it has no reward associated with it.
- Steven Schveighoffer (5/30) Jan 29 2010 Clarity. Disambiguation. All the rewards that come from other naming
- Andrei Alexandrescu (4/36) Jan 29 2010 How is f.byLine clearer and less ambiguous than f.byLine()? Or vice
- Steven Schveighoffer (4/6) Jan 29 2010 Note that properties can be named things other than byLine.
- Andrei Alexandrescu (7/16) Jan 29 2010 What I meant to say is that in the @property landscape the following two...
- Steven Schveighoffer (13/26) Jan 29 2010 I think we all agree that setters the way D1 does them are very prone to...
- Andrei Alexandrescu (9/39) Jan 29 2010 Consider:
- Steven Schveighoffer (9/44) Jan 29 2010 is pop's main purpose to fetch a value or to modify the stack? I'd say ...
- Andrei Alexandrescu (10/60) Jan 29 2010 So now we're down to proportions, nuance, and where "main" goes. You
- Steven Schveighoffer (25/38) Jan 29 2010 You just don't get it. declaring property or not is part of naming the ...
- Michel Fortin (16/35) Jan 29 2010 You win because Steven's definition is not good enough. I said before
- Andrei Alexandrescu (12/42) Jan 29 2010 Ok this makes sense. So something is a property if fetching it doesn't
- Steven Schveighoffer (15/25) Jan 29 2010 No, because pure implies that the object must be immutable. They should...
- Michel Fortin (20/32) Jan 29 2010 Logical-pure, to be precise. ;-)
- Steven Schveighoffer (15/36) Jan 29 2010 Be careful here, don't give Andrei hard criteria for declaring victory ;...
- Michel Fortin (15/33) Jan 29 2010 "some reflection" is a hard criteria now? :-)
- Bill Baxter (15/47) Jan 29 2010 e
- Andrei Alexandrescu (4/8) Jan 29 2010 I agree. It's not the existence of corner cases I'm worried about, it's
- Ary Borenszweig (14/33) Jan 29 2010 The first post of this thread was about not invoking a function when you...
- Andrei Alexandrescu (13/53) Jan 29 2010 Correct. Just that I fear that it's a bit late for this all. It is
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (5/58) Jan 29 2010 How about @property? When you add a @property to a function it can be
- Andrei Alexandrescu (5/71) Jan 29 2010 Such a "@property is just for the writing" design will leave @property
- Lutger (15/24) Jan 29 2010 It's not inconsistent, at most just a bit confusing on the call site.
- Ary Borenszweig (14/70) Jan 29 2010 I think at least for the function/delegate problem, requiring () to
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (3/73) Jan 29 2010 If () is required to invoke delegates, that isn't a problem. First use
- Justin Johansson (4/26) Jan 29 2010 Unless you assume no global state, nullary functions are just
- Andrei Alexandrescu (3/29) Jan 29 2010 Huh? What? Is there an extra "no"?
- Justin Johansson (21/52) Jan 29 2010 No, correct as I meant it. Confusion arises depending on whether you
- Justin Johansson (9/23) Jan 29 2010 Closer to the mark would be ...
- Michel Fortin (7/17) Jan 29 2010 Also
- Justin Johansson (5/21) Jan 29 2010 We could just join in over at
- Michel Fortin (17/29) Jan 29 2010 The problem entirely reside on the ambiguous semantics of 'byLine'. The
- Andrei Alexandrescu (4/33) Jan 29 2010 That's an implementation problem of byLine, not a issue with the byLine
- Michel Fortin (12/13) Jan 29 2010 Ok, so if you agree that 'byLine' eating a line on creation is a bug,
- Lars T. Kyllingstad (14/41) Jan 29 2010 This is a very good point! Using byLine as an argument against
- Justin Johansson (4/7) Jan 29 2010 Obviously that's a rhetorical suggestion by Andrei ... but
- Andrei Alexandrescu (4/41) Jan 29 2010 Yah, though I agree it's nicer to not prime the line in the constructor.
- Steven Schveighoffer (39/78) Jan 29 2010 hm... let me dig it up. (unwillingly)
- Michel Fortin (13/23) Jan 29 2010 You can always define a generic take() like this:
- Steven Schveighoffer (4/21) Jan 29 2010 Except stream ranges. I don't get it...
- Michel Fortin (12/38) Jan 29 2010 Hum, well I used 'take' while you defined 'get' as the basic function
- Steven Schveighoffer (17/47) Jan 29 2010 Oh, I get it now. Yes, you can define this (BTW, I agree take is better...
- Andrei Alexandrescu (4/31) Jan 29 2010 It should work for stream ranges if front() checks the "filled" flag and...
- Steven Schveighoffer (4/33) Jan 29 2010 That actually makes a lot of sense. I hope this fix goes in.
- Andrei Alexandrescu (3/38) Jan 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3752
- Michel Fortin (34/36) Jan 29 2010 So now you want the front to fetch from stdin on the first call? It's
- Steven Schveighoffer (19/26) Jan 29 2010 No, you're reaching here :) What Andrei is doing is acknowledging that ...
- Michel Fortin (29/62) Jan 29 2010 "will not hurt because most of the time"... surely you meant "will not
- Andrei Alexandrescu (5/8) Jan 29 2010 stream.front after stream.popFront works all the time and fetches a new
- Michel Fortin (22/30) Jan 29 2010 The problem is that algorithms that depends on this will work with
- Andrei Alexandrescu (5/25) Jan 29 2010 An algorithm can fail in many silent ways if it misuses the range
- Michel Fortin (40/43) Jan 29 2010 Easy to say. How did you verify that?
- Andrei Alexandrescu (11/33) Jan 29 2010 It's simply a mistake I make very seldom if at all (I don't remember any...
- Andrei Alexandrescu (4/44) Jan 29 2010 I think this is not a problem as much as an organic characteristic of
- Nick Sabalausky (11/15) Jan 29 2010 It's more than just the existence of ambiguous english words. It's also ...
- Michiel Helvensteijn (15/17) Jan 28 2010 If I read the TLP correctly, @property seems not to be working correctly...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (7/22) Jan 28 2010 I don't understand what any of this would improve. Is the byLine example...
- Andrei Alexandrescu (3/36) Jan 28 2010 ++
- Bill Baxter (19/55) Jan 28 2010 y.
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (4/52) Jan 29 2010 A reference to foo.
- Nick Sabalausky (19/25) Jan 28 2010 Class "Foo" has member "bar". Is "bar" a member variable or a member
- Andrei Alexandrescu (5/34) Jan 28 2010 Relax, we're all on the same boat. Unfortunately, your view that it's
- Nick Sabalausky (10/44) Jan 28 2010 The only catches in the idea of the caller seeing it as all data and
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (6/52) Jan 29 2010 I don't think this definition really works. byLine returns a range, so
- Steven Schveighoffer (16/49) Jan 29 2010 Just as every class designer makes up his own rules about naming
- Rainer Deyke (17/19) Jan 29 2010 I disagree.
- Andrei Alexandrescu (9/34) Jan 28 2010 I agree, but I'll also note that I got contradictory opinions from
- Lutger (12/49) Jan 28 2010 Lot's of things are judgement calls, I don't see the problem. @property
- Andrei Alexandrescu (3/61) Jan 28 2010 Wise words. So how do I go about byLine?
- Lutger (8/70) Jan 28 2010 You make a good judgement call :)
- torhu (12/17) Jan 30 2010 I'd say byLine as it's currently implemented in std.stdio is not a
- retard (31/41) Jan 28 2010 I just can't understand why implementing the optional ()s can be so hard...
- Steven Schveighoffer (8/44) Jan 28 2010 No no no. byLine returns a struct, it does not modify stdin. Operating...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (6/10) Jan 29 2010 byLine modifies stdin. If you do this:
- Steven Schveighoffer (25/47) Jan 29 2010 That's a deficiency in the design of byLine. It's a range that "primes"...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (7/23) Jan 29 2010 So byLine should be a property when implemented as a range, and a
- Steven Schveighoffer (38/64) Jan 29 2010 I meant byLine should return a struct that implements opApply. If it is...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (10/12) Jan 29 2010 That's a good point. The writeln = 3; is also a good point. :)
- Steven Schveighoffer (22/35) Jan 29 2010 You've cited three functions where the function names cannot be
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (7/47) Jan 29 2010 I disagree, it doesn't look like it advances. With the parens, it just
- Steven Schveighoffer (6/22) Jan 29 2010 If this were Java, I'd agree with you :) But even on Java, it would hav...
- Andrei Alexandrescu (6/55) Jan 29 2010 "Rules are not meant to be followed robotically."
- Bill Baxter (10/66) Jan 29 2010 ames.
- Michel Fortin (7/9) Jan 29 2010 Hopefully that rule will only apply to the getter. :-)
- Nick Sabalausky (5/18) Jan 29 2010 To me, at a glance, it looks like a series of no-ops. Like "x; y; z;". O...
- Don (4/29) Jan 31 2010 A consequence of this discussion is that the built-in properties
- dsimcha (7/36) Jan 31 2010 Yea, can anyone even come up with a good Devil's Advocate argument in fa...
- bearophile (9/15) Jan 31 2010 I don't know. The built-in sort is certified broken, very slow, and too ...
- torhu (4/26) Jan 31 2010 Before more time is wasted in this discussion, I would like to point out...
I have written the following closure, to generate numbers in 1-7 from numbers in 1-5, as alternative implementation of this: http://rosettacode.org/wiki/Seven-dice_from_Five-dice#D auto dice7Gen(alias d5)() { int rem = 0; int max = 1; int gen7() { while (rem / 7 == max / 7) { while (max < 7) { int rand5 = d5() - 1; max *= 5; rem = 5 * rem + rand5; } int groups = max / 7; if (rem >= 7 * groups) { rem -= 7 * groups; max -= 7 * groups; } } int result = rem % 7; rem /= 7; max /= 7; return result + 1; } return gen7; } Can you spot the bug? It returns an integer instead of a closure :-) The correct last line has to be: return &gen7; But I think the real "bug" here is in the D2 design. In D2 calling callables without () has to be disallowed: - & to take their reference/address - () to call them Otherwise syntax error at compile-time. Only properties marked with property are allowed to be called without (). (If you really want it, then even free functions may be allowed to be marked with property. This probably will not cause many bugs). This can avoid bugs and tidy the language a little more. Bye, bearophile
Jan 26 2010
On 27/01/10 20:34, bearophile wrote:But I think the real "bug" here is in the D2 design. In D2 calling callables without () has to be disallowed: -& to take their reference/address - () to call them Otherwise syntax error at compile-time.Nothing to add except a voice of support.
Jan 27 2010
bearophile wrote:I have written the following closure, to generate numbers in 1-7 from numbers in 1-5, as alternative implementation of this: http://rosettacode.org/wiki/Seven-dice_from_Five-dice#D auto dice7Gen(alias d5)() { int rem = 0; int max = 1; int gen7() { while (rem / 7 == max / 7) { while (max < 7) { int rand5 = d5() - 1; max *= 5; rem = 5 * rem + rand5; } int groups = max / 7; if (rem >= 7 * groups) { rem -= 7 * groups; max -= 7 * groups; } } int result = rem % 7; rem /= 7; max /= 7; return result + 1; } return gen7; } Can you spot the bug? It returns an integer instead of a closure :-) The correct last line has to be: return &gen7; But I think the real "bug" here is in the D2 design. In D2 calling callables without () has to be disallowed: - & to take their reference/address - () to call them Otherwise syntax error at compile-time. Only properties marked with property are allowed to be called without (). (If you really want it, then even free functions may be allowed to be marked with property. This probably will not cause many bugs). This can avoid bugs and tidy the language a little more. Bye, bearophileI thought that this issue had been settled a long time ago, and that this was the whole point of property. -Lars
Jan 27 2010
On 2010-01-27 05:58:51 -0500, "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> said:I thought that this issue had been settled a long time ago, and that this was the whole point of property.It's just not fully implemented yet. The property attribute is there, but it doesn't change how you can call a function. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 27 2010
On 01/27/2010 08:34 AM, bearophile wrote:I have written the following closure, to generate numbers in 1-7 from numbers in 1-5, as alternative implementation of this: http://rosettacode.org/wiki/Seven-dice_from_Five-dice#D auto dice7Gen(alias d5)() { int rem = 0; int max = 1; int gen7() { while (rem / 7 == max / 7) { while (max< 7) { int rand5 = d5() - 1; max *= 5; rem = 5 * rem + rand5; } int groups = max / 7; if (rem>= 7 * groups) { rem -= 7 * groups; max -= 7 * groups; } } int result = rem % 7; rem /= 7; max /= 7; return result + 1; } return gen7; } Can you spot the bug? It returns an integer instead of a closure :-) The correct last line has to be: return&gen7; But I think the real "bug" here is in the D2 design. In D2 calling callables without () has to be disallowed: -& to take their reference/address - () to call them Otherwise syntax error at compile-time. Only properties marked with property are allowed to be called without (). (If you really want it, then even free functions may be allowed to be marked with property. This probably will not cause many bugs). This can avoid bugs and tidy the language a little more. Bye, bearophileI disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.
Jan 27 2010
On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too. -- Adam D. Ruppe http://arsdnet.net
Jan 27 2010
Adam D. Ruppe wrote:On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:Me three.I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On 2010-01-27 14:01:56 -0500, downs <default_357-line yahoo.de> said:Adam D. Ruppe wrote:I'll miss the feature too. But I think it's the right thing to do because otherwise you can't have properties that behave like properties when returning a callable type. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:Me three.I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On 27.01.2010 20:54, Michel Fortin wrote:On 2010-01-27 14:01:56 -0500, downs <default_357-line yahoo.de> said:It may be optically pleasant sometimes to be able to omit the parens, but beside the problem with returning a callable type it's also easier to spot where computations happen instead of fast access to properties, even more in complex expressions. Of course you can hide a bottleneck in a property but I'm talking about the normal case here. And it's not hard to type two parens for better readability.Adam D. Ruppe wrote:I'll miss the feature too. But I think it's the right thing to do because otherwise you can't have properties that behave like properties when returning a callable type.On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:Me three.I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On 01/27/2010 09:53 PM, boscop wrote:On 27.01.2010 20:54, Michel Fortin wrote:I think you're looking for a profiler. I also disagree about the readability part, I dislike line noise.On 2010-01-27 14:01:56 -0500, downs<default_357-line yahoo.de> said:It may be optically pleasant sometimes to be able to omit the parens, but beside the problem with returning a callable type it's also easier to spot where computations happen instead of fast access to properties, even more in complex expressions. Of course you can hide a bottleneck in a property but I'm talking about the normal case here. And it's not hard to type two parens for better readability.Adam D. Ruppe wrote:I'll miss the feature too. But I think it's the right thing to do because otherwise you can't have properties that behave like properties when returning a callable type.On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle M�nsson wrote:Me three.I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
"downs" <default_357-line yahoo.de> wrote in message news:hjq2l1$1s5j$1 digitalmars.com...Adam D. Ruppe wrote:Meh, I hate it hate it hate it hate it hate it. I'd dance on the feature's grave. So I guess you could say I wouldn't miss it. ;)On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:Me three.I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On Wed, 27 Jan 2010 23:50:26 +0300, Nick Sabalausky <a a.a> wrote:"downs" <default_357-line yahoo.de> wrote in message news:hjq2l1$1s5j$1 digitalmars.com...anAdam D. Ruppe wrote:On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle M=C3=A5nsson wrote:I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's =Meh, I hate it hate it hate it hate it hate it. I'd dance on the =Me three.integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.feature's grave. So I guess you could say I wouldn't miss it. ;)Me too!
Jan 27 2010
downs wrote:Adam D. Ruppe wrote:There was a long discussion about that, which prompted the addition of property. I was in the anti- property camp, but had understanding and sympathy for the ambiguity issues involved without property. There was a vote in which as far as I recall the pro- property camp was beaten to a tender pulp. Now property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision. AndreiOn Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle Månsson wrote:Me three.I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On 01/27/2010 09:54 PM, Andrei Alexandrescu wrote:downs wrote:Not just parameterless functions, but functions operating on arrays as well. And mostly anything, if I recall correctly.Adam D. Ruppe wrote:There was a long discussion about that, which prompted the addition of property. I was in the anti- property camp, but had understanding and sympathy for the ambiguity issues involved without property. There was a vote in which as far as I recall the pro- property camp was beaten to a tender pulp. Now property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision. AndreiOn Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle M�nsson wrote:Me three.I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.
Jan 27 2010
On 2010-01-27 15:54:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Now property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision.Well, perhaps it'd be better if it was 'property' instead of ' property'. I find the distinction between keywords and attributes to be pretty arbitrary, almost illogical. I'm on the side that attributes (those keywords starting with ) should be reserved to things you can ignore entirely without preventing the program from working. For instance, remove all safe and trusted attributes from a program and it still works with no change in behaviour (except for when an error occurs). 'nothrow', 'pure', 'final', 'deprecated' should be attributes; ' property' should be a regular keyword. Protection attributes could be made attributes too since if you remove them all everything still works. So I think attributes should be reserved to non-essential but useful stuff in the language, generally those things adding restrictions without changing the semantics. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 27 2010
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:hjqdca$2neo$1 digitalmars.com...On 2010-01-27 15:54:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Yes, agreed, there should be some more thought put into how keywords work so that things are consistent and make sense. It seems strange that new keywords are preceded by , but older ones are not. However, aesthetically, I prefer the to a double underscore. Perhaps __gshared could be gshared or even shared. -Craig -CraigNow property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision.Well, perhaps it'd be better if it was 'property' instead of ' property'. I find the distinction between keywords and attributes to be pretty arbitrary, almost illogical. I'm on the side that attributes (those keywords starting with ) should be reserved to things you can ignore entirely without preventing the program from working. For instance, remove all safe and trusted attributes from a program and it still works with no change in behaviour (except for when an error occurs). 'nothrow', 'pure', 'final', 'deprecated' should be attributes; ' property' should be a regular keyword. Protection attributes could be made attributes too since if you remove them all everything still works. So I think attributes should be reserved to non-essential but useful stuff in the language, generally those things adding restrictions without changing the semantics.
Jan 27 2010
Michel Fortin wrote:On 2010-01-27 15:54:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:This was actually discussed before, and I think the general conclusion was that there is no useful definition of attributes that includes property. I think I have an idea quite similar to yours, only slightly more specific. I'll post it in a new thread. -LarsNow property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision.Well, perhaps it'd be better if it was 'property' instead of ' property'. I find the distinction between keywords and attributes to be pretty arbitrary, almost illogical. I'm on the side that attributes (those keywords starting with ) should be reserved to things you can ignore entirely without preventing the program from working. For instance, remove all safe and trusted attributes from a program and it still works with no change in behaviour (except for when an error occurs). 'nothrow', 'pure', 'final', 'deprecated' should be attributes; ' property' should be a regular keyword. Protection attributes could be made attributes too since if you remove them all everything still works. So I think attributes should be reserved to non-essential but useful stuff in the language, generally those things adding restrictions without changing the semantics.
Jan 28 2010
On Wed, 27 Jan 2010 15:54:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:downs wrote:1. Choosing between including property or not is rare. Most cases are obvious. If you worked with a language that requires property notation 2. Defining property on functions you wish to call as properties can be done all at once, enclosing all properties in a property { } block. No need to "litter" all your code with that. Furthermore, function signature 'documentation' is not as littering as you think. Verbosity at definition is not as cumbersome as verbosity at the call site. In other words, the extra litter at definition time pays huge dividends in clarity at the call site, and is not a constant annoyance (you only define things once). I'm sure C developers who were used to omitting prototypes were equally miffed when it became required. -SteveAdam D. Ruppe wrote:There was a long discussion about that, which prompted the addition of property. I was in the anti- property camp, but had understanding and sympathy for the ambiguity issues involved without property. There was a vote in which as far as I recall the pro- property camp was beaten to a tender pulp. Now property is in. That has created (as I had anticipated) the unresolved issue of choosing between property or just function for any given parameterless function. Also I need to litter my code with property. To this day I am not sure whether we made the right decision.On Wed, Jan 27, 2010 at 06:34:57PM +0100, Pelle MÃ¥nsson wrote:Me three.I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.Me too.
Jan 28 2010
Steven Schveighoffer wrote:1. Choosing between including property or not is rare. Most cases are obvious. If you worked with a language that requires property notationI need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.2. Defining property on functions you wish to call as properties can be done all at once, enclosing all properties in a property { } block. No need to "litter" all your code with that. Furthermore, function signature 'documentation' is not as littering as you think. Verbosity at definition is not as cumbersome as verbosity at the call site. In other words, the extra litter at definition time pays huge dividends in clarity at the call site, and is not a constant annoyance (you only define things once).OK. The problem is, I was already enjoying clarity at the call site. So for me the whole property thing has a much less appeal than it might. I do appreciate that property eliminates ambiguities in corner cases.I'm sure C developers who were used to omitting prototypes were equally miffed when it became required.That situation is different. There's only one possible prototype a function can have. With property, it's anyone's guess. Andrei
Jan 28 2010
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:Because it's an action, not a property. Simple as that. :) Actually, the functions you mention are probably the best examples of why the property attribute is so cool. Using it, you can signify that empty tests for emptiness, and doesn't empty() the range or container. Rule of thumb: noun or adjective --> property verb --> not property -Lars -Lars1. Choosing between including property or not is rare. Most cases are obvious. If you worked with a language that requires propertyI need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.
Jan 28 2010
On Thu, 28 Jan 2010 08:57:15 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Because popFront isn't a property. It doesn't return anything, does it? A property either fetches a value or sets a value. Defining anything else as a property is disingenuous, and that was the original problem -- you could make it look like you were accessing a property when you really aren't. popFront should not be a property and should always have parentheses after it.1. Choosing between including property or not is rare. Most cases are obvious. If you worked with a language that requires property notationI need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.You are governed by your personal restrictions and taste. The problem is that left to their own devices, people will use their own style of calling functions. Some will always use parentheses even when the function is supposed to be a property, others will always avoid parentheses when they can, yet others will be somewhere in between. The end result is you have code that is not intuitive to you if the author doesn't follow your style. At least with a property requirement, there is only one style.2. Defining property on functions you wish to call as properties can be done all at once, enclosing all properties in a property { } block. No need to "litter" all your code with that. Furthermore, function signature 'documentation' is not as littering as you think. Verbosity at definition is not as cumbersome as verbosity at the call site. In other words, the extra litter at definition time pays huge dividends in clarity at the call site, and is not a constant annoyance (you only define things once).OK. The problem is, I was already enjoying clarity at the call site. So for me the whole property thing has a much less appeal than it might. I do appreciate that property eliminates ambiguities in corner cases.the similarity is that an optional specification became required because it was confusing when you went to use the function how to call it. I agree the similarity is not 1 to 1, but what I meant to point out is that people who started with ANSI C (myself included) never missed that feature. Only those who used the feature would be upset. Likewise, I would never miss the optional-parens style of a function that's not a property because I never really got used to doing it. So do you miss it because it had true benefits or because you're just used to doing it that way? -SteveI'm sure C developers who were used to omitting prototypes were equally miffed when it became required.That situation is different. There's only one possible prototype a function can have. With property, it's anyone's guess.
Jan 28 2010
Andrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:Steven Schveighoffer wrote:Because it denotes an action? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------1. Choosing between including property or not is rare. Most cases are obvious. If you worked with a language that requires you.I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.
Jan 28 2010
On Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Andrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront(); I wonder if there is some correlation between old assembly programmers and newer language users on this issue. In assembly, there's no distinction; you write all instructions and many macros without parens, so it is no weird thing. -- Adam D. Ruppe http://arsdnet.netI need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:On Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like read;. If there were a way to enforce "only terms that are clearly denote actions can be called without parentheses," I'd be all for it. -SteveAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
On 01/28/2010 04:28 PM, Steven Schveighoffer wrote:On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:I do not understand why this is damage at all. It's like collateral fluff, not collateral damage. Also, is there any case where a function is not a property and do not denote an action but is still callable without parenthesis? Aside from bad naming, of course.On Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like read;. If there were a way to enforce "only terms that are clearly denote actions can be called without parentheses," I'd be all for it. -SteveAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
Steven Schveighoffer wrote:On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
On Thu, 28 Jan 2010 20:28:17 +0300, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:Steven Schveighoffer wrote:Great explanation, very convincing!On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
Denis Koroskin wrote:On Thu, 28 Jan 2010 20:28:17 +0300, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:How about this: foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose? AndreiSteven Schveighoffer wrote:Great explanation, very convincing!On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
On 01/28/2010 09:59 PM, Andrei Alexandrescu wrote:Denis Koroskin wrote:I say you don't, it works both ways as it is now. I say, let's not remove this feature :) property should be for when you need to assign to it. Maybe.On Thu, 28 Jan 2010 20:28:17 +0300, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:How about this: foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose? AndreiSteven Schveighoffer wrote:Great explanation, very convincing!On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
Pelle MÃ¥nsson wrote:On 01/28/2010 09:59 PM, Andrei Alexandrescu wrote:I think there are 3 cases: (1) I want this to _always_ be treated as if it were a field; (2) I want this to _always_ be treated as a function; (3) I don't care. (this arises most frequently in generic code: you're forced to choose between a field and a function, but you can't have both). D1 caters for case (3) very well, but does extremely poorly for (1) and (2). property is perfect for case (1). It also seems reasonable to disallow property assignment syntax for anything which isn't marked as property. Disallowing removable parentheses for no-parameter functions is the contentious part.Denis Koroskin wrote:I say you don't, it works both ways as it is now. I say, let's not remove this feature :) property should be for when you need to assign to it. Maybe.On Thu, 28 Jan 2010 20:28:17 +0300, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:How about this: foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose? AndreiSteven Schveighoffer wrote:Great explanation, very convincing!On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
Don wrote:I think there are 3 cases: (1) I want this to _always_ be treated as if it were a field; (2) I want this to _always_ be treated as a function; (3) I don't care. (this arises most frequently in generic code: you're forced to choose between a field and a function, but you can't have both). D1 caters for case (3) very well, but does extremely poorly for (1) and (2). property is perfect for case (1). It also seems reasonable to disallow property assignment syntax for anything which isn't marked as property. Disallowing removable parentheses for no-parameter functions is the contentious part.Good summary. I now wonder, could one overload based on property? auto a = container.empty; // check for emptiness container.empty(); // take the trash out ! Anyway, I have one more comment about the example: foreach (line; stdio.byLine) { ... } vs. foreach (line; stdio.byLine()) { ... } Steve said, byLine fetches a range off stdio. In fact it's not - it's an opApply() based loop. That already muddies the waters. But I have another, bigger concern. When I think of a property, I think I fetch it and it can't go back and modify its originator. Like if I do: auto x = y.length; I don't expect to later mess with x and change y through it. I'm sure an inventive mind could find an argument against this but if I try to be honest with myself I'd think it's tenuous to have the tail property wag the dog object. Unfortunately that's exactly what happens with stdin.byLine: even if it were a range, it would alter stdin through its usage. It's not a property in the same way stdin.eof or stdin.isOpen are. Andrei
Jan 28 2010
Andrei Alexandrescu wrote:Don wrote:I was mistaken. byLine does fetch a range. http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/stdio.d BTW I love byLine. AndreiI think there are 3 cases: (1) I want this to _always_ be treated as if it were a field; (2) I want this to _always_ be treated as a function; (3) I don't care. (this arises most frequently in generic code: you're forced to choose between a field and a function, but you can't have both). D1 caters for case (3) very well, but does extremely poorly for (1) and (2). property is perfect for case (1). It also seems reasonable to disallow property assignment syntax for anything which isn't marked as property. Disallowing removable parentheses for no-parameter functions is the contentious part.Good summary. I now wonder, could one overload based on property? auto a = container.empty; // check for emptiness container.empty(); // take the trash out ! Anyway, I have one more comment about the example: foreach (line; stdio.byLine) { ... } vs. foreach (line; stdio.byLine()) { ... } Steve said, byLine fetches a range off stdio. In fact it's not - it's an opApply() based loop.
Jan 28 2010
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt1ea$306u$1 digitalmars.com...Good summary. I now wonder, could one overload based on property? auto a = container.empty; // check for emptiness container.empty(); // take the trash out !Why would that ever enter into anyone's mind? You already can't overload on a member's type, you already can't overload on function's return type, and you certainly can't overload on a mere decorator. There's no issue here.Anyway, I have one more comment about the example: foreach (line; stdio.byLine) { ... } vs. foreach (line; stdio.byLine()) { ... } Steve said, byLine fetches a range off stdio. In fact it's not - it's an opApply() based loop. That already muddies the waters. But I have another, bigger concern. When I think of a property, I think I fetch it and it can't go back and modify its originator. Like if I do: auto x = y.length; I don't expect to later mess with x and change y through it. I'm sure an inventive mind could find an argument against this but if I try to be honest with myself I'd think it's tenuous to have the tail property wag the dog object.If you see a problem with being able to do this: auto dog = new Dog(); auto tail = dog.tail; tail.wag(); Then you obviously haven't done much game programming. (Now obviously something like "tail.bark()" would be ridiculous, but hardly a real risk.) Additionally, even if that could be considered a problem, I don't see how having ommittable parens on no-param function calls would in any way alleviate the problem.
Jan 28 2010
Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt1ea$306u$1 digitalmars.com...Nonono, the expression "tail wagging the dog" means that the actual tail stands still and the dog is shaking like a tail. AndreiGood summary. I now wonder, could one overload based on property? auto a = container.empty; // check for emptiness container.empty(); // take the trash out !Why would that ever enter into anyone's mind? You already can't overload on a member's type, you already can't overload on function's return type, and you certainly can't overload on a mere decorator. There's no issue here.Anyway, I have one more comment about the example: foreach (line; stdio.byLine) { ... } vs. foreach (line; stdio.byLine()) { ... } Steve said, byLine fetches a range off stdio. In fact it's not - it's an opApply() based loop. That already muddies the waters. But I have another, bigger concern. When I think of a property, I think I fetch it and it can't go back and modify its originator. Like if I do: auto x = y.length; I don't expect to later mess with x and change y through it. I'm sure an inventive mind could find an argument against this but if I try to be honest with myself I'd think it's tenuous to have the tail property wag the dog object.If you see a problem with being able to do this: auto dog = new Dog(); auto tail = dog.tail; tail.wag();
Jan 28 2010
On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Denis Koroskin wrote:byLine is a property. It is fetching a range on stdin. -SteveOn Thu, 28 Jan 2010 20:28:17 +0300, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:How about this: foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?Steven Schveighoffer wrote:Great explanation, very convincing!On Thu, 28 Jan 2010 10:22:45 -0500, Adam D. Ruppe <destructionator gmail.com> wrote:...or, as in Andrei's example, 'empty'. In Java you'd write isEmpty(), or even worse, getEmpty(). In D we now have the option of declaring it a property, with little chance of people thinking it actually empties anything. -LarsOn Thu, Jan 28, 2010 at 11:47:45AM -0300, Leandro Lucarella wrote:Whether you use parentheses or not, it's not a property. The statement of Andrei is that he doesn't know why it's not a property. The simple reason is because it's an action. Now, does popFront; look like an action? Yes. But that is not the case being disambiguated. It is collateral damage. Because the compiler doesn't understand English, it can't know whether to disallow popFront; any more than an ambiguous term like readAndrei Alexandrescu, el 28 de enero a las 07:57 me escribiste:I don't think it is that simple - I see popFront; as an action all the same as popFront();I need to put it for all front() and empty() declarations. By the way I decided that popFront() is not a property. I don't know why.Because it denotes an action?
Jan 28 2010
Steven Schveighoffer wrote:On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different. Andreiforeach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -Steve
Jan 28 2010
On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Maybe "property" is a misleading word. Clearly there are more things to which that applies than just what the traditional definition of the word would imply. I would not in English call my nose a "property" of me, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the use of "get" and "set" perhaps does a better job of conveying this. --bbOn Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. =A0It is fetching a range on stdin. -Steve
Jan 28 2010
Bill Baxter wrote:On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:This raises the hair on my back. It's back to programming-by-convention. AndreiSteven Schveighoffer wrote:Maybe "property" is a misleading word. Clearly there are more things to which that applies than just what the traditional definition of the word would imply. I would not in English call my nose a "property" of me, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the use of "get" and "set" perhaps does a better job of conveying this.On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -Steve
Jan 28 2010
On Thu, Jan 28, 2010 at 2:07 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:Wait, you started off by saying "how do I decide?" and we give you a rule you can follow to decide and now you say you don't like it because it's programming-by-convention? I guess I don't really understand what your argument is. --bbOn Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:This raises the hair on my back. It's back to programming-by-convention.Steven Schveighoffer wrote:Maybe "property" is a misleading word. =A0Clearly there are more things to which that applies than just what the traditional definition of the word would imply. =A0I would not in English call my nose a "property" of me, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the use of "get" and "set" perhaps does a better job of conveying this.On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. =A0It is fetching a range on stdin. -Steve
Jan 28 2010
Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:07 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It's not a rule. It's several contradictory ones. AndreiBill Baxter wrote:Wait, you started off by saying "how do I decide?" and we give you a rule you can follow to decide and now you say you don't like it because it's programming-by-convention? I guess I don't really understand what your argument is.On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:This raises the hair on my back. It's back to programming-by-convention.Steven Schveighoffer wrote:Maybe "property" is a misleading word. Clearly there are more things to which that applies than just what the traditional definition of the word would imply. I would not in English call my nose a "property" of me, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the use of "get" and "set" perhaps does a better job of conveying this.On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -Steve
Jan 28 2010
On Thu, Jan 28, 2010 at 2:25 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:sOn Thu, Jan 28, 2010 at 2:07 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Maybe "property" is a misleading word. =A0Clearly there are more thing=On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. =A0It is fetching a range on stdin. -Steveofto which that applies than just what the traditional definition of the word would imply. =A0I would not in English call my nose a "property" =alme, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the.use of "get" and "set" perhaps does a better job of conveying this.This raises the hair on my back. It's back to programming-by-convention=Please point out the contradictions. I'm not seeing them. --bbWait, you started off by saying "how do I decide?" and we give you a rule you can follow to decide and now you say you don't like it because it's programming-by-convention? =A0 I guess I don't really understand what your argument is.It's not a rule. It's several contradictory ones.
Jan 28 2010
Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:25 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Some said it should be stdin.byLine(), some others said it should be stdin.byLine. They invoked contradictory rules that led to contradictory conclusions. AndreiBill Baxter wrote:Please point out the contradictions. I'm not seeing them.On Thu, Jan 28, 2010 at 2:07 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It's not a rule. It's several contradictory ones.Bill Baxter wrote:Wait, you started off by saying "how do I decide?" and we give you a rule you can follow to decide and now you say you don't like it because it's programming-by-convention? I guess I don't really understand what your argument is.On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:This raises the hair on my back. It's back to programming-by-convention.Steven Schveighoffer wrote:Maybe "property" is a misleading word. Clearly there are more things to which that applies than just what the traditional definition of the word would imply. I would not in English call my nose a "property" of me, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additional information (and which doesn't change the outwardly visible state the use of "get" and "set" perhaps does a better job of conveying this.On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -Steve
Jan 28 2010
On Thu, Jan 28, 2010 at 2:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:ngsOn Thu, Jan 28, 2010 at 2:25 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:07 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:On Thu, Jan 28, 2010 at 1:26 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Maybe "property" is a misleading word. =A0Clearly there are more thi=On Thu, 28 Jan 2010 15:59:30 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. =A0It is fetching a range on stdin. -Steveheto which that applies than just what the traditional definition of t=" ofword would imply. =A0I would not in English call my nose a "property=lme, but if I were a D object and had a .nose accessor, I would certainly think that accessor would qualify as a D property. How's this: anything that you can "get" without specifying additiona=einformation (and which doesn't change the outwardly visible state th=cialOk, I thought you were saying my rule was somehow self-contradictory. I understand what you mean now. Just that the rule to apply is not obvious. But I think that applies to many things in computer programming. Whether to use pointers or references. Whether to use classes or struct. Whether to make something private or protected, or virtual or non-virtual. Some cases are obvious, others are not. --bbSome said it should be stdin.byLine(), some others said it should be stdin.byLine. They invoked contradictory rules that led to contradictory conclusions.Please point out the contradictions. =A0I'm not seeing them.It's not a rule. It's several contradictory ones.Wait, you started off by saying "how do I decide?" and we give you a rule you can follow to decide and now you say you don't like it because it's programming-by-convention? =A0 I guess I don't really understand what your argument is.use of "get" and "set" perhaps does a better job of conveying this.This raises the hair on my back. It's back to programming-by-convention.
Jan 28 2010
Hello, I think the biggest part of our problem with property is, that we are using the wrong words. I'm no native english speaker so it may be that i'm totaly wrong with this, but that's my impression. When i hear the word property i'm thinking: "ok, this is a well defined part of the internal state of that object instance that i'm allowed to interact with". That's what i think a property is. It is not about parentheses or not parentheses. It is not about just marking functions to change their call behaviour. I think a property should be about *first* naming and defining a distinct part of the object state and thereafter *optionally* defining how to deal with it. I really don't want to talk much about syntax but i like the way Moose has solved this problem for Perl5. Even if its syntax is not compatible to a C derived language language like D (btw. why not?), a quick skim of its documentation may be a source of inspiration. It clearly was for me. http://search.cpan.org/~drolsky/Moose-0.94/lib/Moose.pm The coolest thing about Moose is, that it doesn't change the language of Perl5 in any way. For attributes (their name for properties) it just implements a declarative syntax that is valid perl code and executed at compile time to define fields and accessor functions. so a simple has 'x' => (is => 'rw', isa => 'Int'); just defines a field that can hold an integer and two accessor functions x() and x(int). The name of the real field and how it is stored is adjustable but defaults to the way perl objects are normaly constructed. has 'x' => (is => 'ro', isa => 'Int'); just omits constructing a write accessor. To be exact at this a readonly property doesn't mean it is const, it means that you don't have a write accessor and therefore can't substitute its content. You can get a mutable subobject or struct via a read accesseor and manipulate it via its own property accessors but you can't substitute it since you have no write accessor. If you don't want to let the client manipulate intenal state via a read accessor of a complex property just make it return a const subobject. Semantically this turns a property into a little sub-class even if it is not defined as such. It is implemented as old school fields and accessor functions. But they are auto generated until you feel the need to define them explicitly. There are much more ideas in Moose that may be applicable to D that i won't go any deeper in here. Please skim it's documentation if you're interested. For me it has turned Perl into something beautiful while being extremly flexible. But I don't want to advertise any Perl, just hoping the idees behind Moose can be helpful. So back to D. The simplest property definition i can think of ist this: class c { public: int a; } This can be interpreted as a property with name 'a' that has compiler generated accessor functions int a(), and a (int) or int a(int) .The compiler can not only auto generate them, it can also opimize them away. So at the end of the day a field can be seen as an optimized property. This implicates that i should be able to access fields using accessor function syntax. Yes, i really mean someting like x = c.a() or c.a( x) also for field access. Even auto old = c.a( x) may be usefull. I think this can be essential for templates or meta programming. Syntax like x = c.a or c.a = x is cute but should be rewritten to the above by the compiler and then optimized away in case of auto-generated accessors. The whole talk about using parentheses or not for accessor functions, just to better distinguish accessors from real fields when reading D sources i have a really simple solution for. Just conceptually get rid of real fields in objects. Then we don't have to distinguish. And if "int a;" in a class definition simply defines a lightweight rw property that internally is implemented by the compiler as a field, we get the benefits of real properties for each field without changing one line of already written source code. The danger of confusing field access with a function call omitting empty parentheses vanishes as well because every field access is now consequently a call of a property accessor even when optimized away. So function calls can safely omit empty parentheses without being ambigious. Then later we can think about creating a DSL that helps us to *declare* more complex types of properties and have the compiler construct the implicit parts at compile time. For instance i can think of a boolean property that has a toggle accessor. We shouldn't compose our classes from fields and functions that we declare to be called with or without parentheses. We should compose our classes from properties we declare (public, privat or whatever) and let the compiler do the boring work for us. Now to your problem with byLine:stdin.byLine. They invoked contradictory rules that led to contradictory conclusions. If byLine internally constructs a new range instance that happens to use stdin for iterating by line, this to me ist clearly a function. And then the normal rules for calling a function in the D language must apply. This has nothing to do with properties. If you have a single ByLineRange instance stored in stdin that is simply handed out by the byLine function, than this can be seen as a getter function of a byLine property and *both* forms should be applicable. So, that is my opinion about properties. I hope it makes some sense to you or is helpful to anyone. -- GerritSome said it should be stdin.byLine(), some others said it should be
Jan 29 2010
On 2010-01-29 17:22:11 -0500, Gerrit Wichert <gw green-stores.de> said:[skipping a long part] But I don't want to advertise any Perl, just hoping the idees behind Moose can be helpful. So back to D.Objective-C properties look like that too. You declare a property with a name, a type and some flags (like readonly), and you can either provide your own accessor functions or tell the compiler to synthesize them. All this reminds me the debate about what to do with properties a long time ago. Walter finally settled for property, so that's what we have now. I don't really want to reopen the debate. Thinking about it, I'm wondering if property wouldn't be better named as accessor. After all, each function labeled property isn't a property in itself, it's an accessor for that property constituted of all the overloaded accessor functions having the same name. But that's just a small cosmetic issue and I don't mind very much.Now to your problem with byLine:I think that's not exactly how it should be. I'd rather say: if you can conceptualize stdin as containing a ByLineRange then it is fit as a property. The actual implementation of stdin and byLine shouldn't matter.Some said it should be stdin.byLine(), some others said it should be stdin.byLine. They invoked contradictory rules that led to contradictory conclusions.If byLine internally constructs a new range instance that happens to use stdin for iterating by line, this to me ist clearly a function. And then the normal rules for calling a function in the D language must apply. This has nothing to do with properties. If you have a single ByLineRange instance stored in stdin that is simply handed out by the byLine function, than this can be seen as a getter function of a byLine property and *both* forms should be applicable.So, that is my opinion about properties. I hope it makes some sense to you or is helpful to anyone.It makes sense in that it's a valid way to think about properties. I just don't feel it's worth reopening that debate now that we have something. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Andrei Alexandrescu wrote:byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story. A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging. Omitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes. -- Michiel HelvensteijnDamn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -Steve
Jan 28 2010
On Thu, Jan 28, 2010 at 1:55 PM, Michiel Helvensteijn <m.helvensteijn.remove gmail.com> wrote:Andrei Alexandrescu wrote:dbyLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it woul=Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. =A0It is fetching a range on stdin. -Stevebe a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin. --bb
Jan 28 2010
Bill Baxter wrote:Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy. -- Michiel HelvensteijnbyLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
Michiel Helvensteijn wrote:Bill Baxter wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head. AndreiAh, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
On Thu, Jan 28, 2010 at 2:11 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Michiel Helvensteijn wrote:I really don't see what the problem is there. You are arguing that car.wheels should not be a property simply because it would let me change the color of the wheels (which are part of the car's total state)? --bbBill Baxter wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:11 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin. AndreiMichiel Helvensteijn wrote:I really don't see what the problem is there. You are arguing that car.wheels should not be a property simply because it would let me change the color of the wheels (which are part of the car's total state)?Bill Baxter wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
On Thu, Jan 28, 2010 at 2:27 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. Doesn't seem like it should matter to me. --bbOn Thu, Jan 28, 2010 at 2:11 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.Michiel Helvensteijn wrote:I really don't see what the problem is there. You are arguing that car.wheels should not be a property simply because it would let me change the color of the wheels (which are part of the car's total state)?Bill Baxter wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:27 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:If you access car.wheel, it is reasonable to repaint that wheel. The problem is that you can use car.wheel to repaint the car. AndreiBill Baxter wrote:Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. Doesn't seem like it should matter to me.On Thu, Jan 28, 2010 at 2:11 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.Michiel Helvensteijn wrote:I really don't see what the problem is there. You are arguing that car.wheels should not be a property simply because it would let me change the color of the wheels (which are part of the car's total state)?Bill Baxter wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.That's not how it works, I think. Just calling byLine() by itself only returns a range struct. Consuming things from that range is what changes the state of stdin.
Jan 28 2010
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt449$5d8$1 digitalmars.com...Bill Baxter wrote:Ok, so you don't think a property of something should be able to change other parts of that something? Ok, I can understand that. But if that's so, then how would it be any better to be able to change something through the return value of one of that something's member functions? (Which, of course, is what stdin.byLine apperently already does.) Ie, Given this code: auto foo = stdin.byLine; foo.doSomethingThatAdvancesStdin(); How is it possible for that code to be bad when "byLine" is defined as a " property", but suddenly be perfectly fine when omittable parens are allowed and it's defined without " property", even though either way it's still the exact same code doing exactly the same thing and having exactly the same effects?On Thu, Jan 28, 2010 at 2:27 PM, Andrei AlexandrescuIf you access car.wheel, it is reasonable to repaint that wheel. The problem is that you can use car.wheel to repaint the car.The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. Doesn't seem like it should matter to me.
Jan 28 2010
On Thu, Jan 28, 2010 at 3:58 PM, Nick Sabalausky <a a.a> wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt449$5d8$1 digitalmars.com...sBill Baxter wrote:On Thu, Jan 28, 2010 at 2:27 PM, Andrei AlexandrescuThe problem is not localized change. The result of stdin.byLine change=mthe _entire_ stdin.Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. =A0Doesn't see=o,Ok, so you don't think a property of something should be able to change other parts of that something? Ok, I can understand that. But if that's s=like it should matter to me.If you access car.wheel, it is reasonable to repaint that wheel. The problem is that you can use car.wheel to repaint the car.then how would it be any better to be able to change something through th=ereturn value of one of that something's member functions? (Which, of cour=se,is what stdin.byLine apperently already does.) Ie, Given this code: auto foo =3D stdin.byLine; foo.doSomethingThatAdvancesStdin(); How is it possible for that code to be bad when "byLine" is defined as a " property", but suddenly be perfectly fine when omittable parens are allowed and it's defined without " property", even though either way it's still the exact same code doing exactly the same thing and having exactly the same effects?That's not a contradiction in Andrei's position at all. Because if there is no property, then all that dropping parens means is that it's a no-function argument. In the original D1 scheme, .foo just means foo is either field or a zero-arg function. Nothing more nothing less. The problem is that you can't tell if the coder meant it to be a property or not, and this bites you in cases like returning callable. --bb
Jan 28 2010
"Bill Baxter" <wbaxter gmail.com> wrote in message news:mailman.47.1264724411.4461.digitalmars-d puremagic.com...On Thu, Jan 28, 2010 at 3:58 PM, Nick Sabalausky <a a.a> wrote:I assume you meant "no-argument function". And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt449$5d8$1 digitalmars.com...That's not a contradiction in Andrei's position at all. Because if there is no property, then all that dropping parens means is that it's a no-function argument.Bill Baxter wrote:Ok, so you don't think a property of something should be able to change other parts of that something? Ok, I can understand that. But if that's so, then how would it be any better to be able to change something through the return value of one of that something's member functions? (Which, of course, is what stdin.byLine apperently already does.) Ie, Given this code: auto foo = stdin.byLine; foo.doSomethingThatAdvancesStdin(); How is it possible for that code to be bad when "byLine" is defined as a " property", but suddenly be perfectly fine when omittable parens are allowed and it's defined without " property", even though either way it's still the exact same code doing exactly the same thing and having exactly the same effects?On Thu, Jan 28, 2010 at 2:27 PM, Andrei AlexandrescuIf you access car.wheel, it is reasonable to repaint that wheel. The problem is that you can use car.wheel to repaint the car.The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. Doesn't seem like it should matter to me.
Jan 28 2010
Nick Sabalausky wrote:"Bill Baxter" <wbaxter gmail.com> wrote in message news:mailman.47.1264724411.4461.digitalmars-d puremagic.com...Because a function doesn't attempt to emulate a field. AndreiOn Thu, Jan 28, 2010 at 3:58 PM, Nick Sabalausky <a a.a> wrote:I assume you meant "no-argument function". And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjt449$5d8$1 digitalmars.com...That's not a contradiction in Andrei's position at all. Because if there is no property, then all that dropping parens means is that it's a no-function argument.Bill Baxter wrote:Ok, so you don't think a property of something should be able to change other parts of that something? Ok, I can understand that. But if that's so, then how would it be any better to be able to change something through the return value of one of that something's member functions? (Which, of course, is what stdin.byLine apperently already does.) Ie, Given this code: auto foo = stdin.byLine; foo.doSomethingThatAdvancesStdin(); How is it possible for that code to be bad when "byLine" is defined as a " property", but suddenly be perfectly fine when omittable parens are allowed and it's defined without " property", even though either way it's still the exact same code doing exactly the same thing and having exactly the same effects?On Thu, Jan 28, 2010 at 2:27 PM, Andrei AlexandrescuIf you access car.wheel, it is reasonable to repaint that wheel. The problem is that you can use car.wheel to repaint the car.The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.Ok, so you have no problem with a car.wheels returning a mutable wheels object? So it's only when the returned property can change the entire state (or a lot of the state?) that you have a problem? I don't understand how degree changes the acceptability. Doesn't seem like it should matter to me.
Jan 28 2010
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 28 2010
Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention. AndreiNick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 28 2010
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtet5$111d$1 digitalmars.com...Nick Sabalausky wrote:A programming language *is* a set of enforced conventions. When something either can't be enforced mechanically (ex: accurate and meaningful variable names), or has real practical value in not having an enforced convention (ex: user-definable variable names, free-form whitespace, underscores in numeric literals), that's when it's left to the users to make up their own arbitrary and likely-conflicting conventions. Arbitrary freedoms just for the sake of it: great in real life, lousy in a programming language. If we don't enforce the convention of (non-property) functions being called with parens, the only things gained besides that useless "arbitrary freedom in a programming language just for the sake of it" is a couple fewer keystrokes and an extremely minuscule reduction in alleged "noise" (the usefulness of which is easily canceled out by the fact that reduction in inconsistency improves readability too)."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention.Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 28 2010
"Nick Sabalausky" <a a.a> wrote in message news:hjtl33$1dag$1 digitalmars.com..."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtet5$111d$1 digitalmars.com...We can keep dancing around it with different evidence, metaphors and philosophies all we want, but the bottom line is, omittable parens are a feature, and they just happen to be a feature that 1. causes problems and 2. provides extremely minimal benefits. And what do we do with features that cause problems and provide extremely minimal benefits? We yank 'em.Nick Sabalausky wrote:A programming language *is* a set of enforced conventions. When something either can't be enforced mechanically (ex: accurate and meaningful variable names), or has real practical value in not having an enforced convention (ex: user-definable variable names, free-form whitespace, underscores in numeric literals), that's when it's left to the users to make up their own arbitrary and likely-conflicting conventions. Arbitrary freedoms just for the sake of it: great in real life, lousy in a programming language. If we don't enforce the convention of (non-property) functions being called with parens, the only things gained besides that useless "arbitrary freedom in a programming language just for the sake of it" is a couple fewer keystrokes and an extremely minuscule reduction in alleged "noise" (the usefulness of which is easily canceled out by the fact that reduction in inconsistency improves readability too)."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention.Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 28 2010
Nick Sabalausky wrote:"Nick Sabalausky" <a a.a> wrote in message news:hjtl33$1dag$1 digitalmars.com...Creeping elegance is the root of all evil.*** (***Variation on a theme attributed to exactly-one famous computer scientist.) Best wishes, Justin Johansson"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtet5$111d$1 digitalmars.com...We can keep dancing around it with different evidence, metaphors and philosophies all we want, but the bottom line is, omittable parens are a feature, and they just happen to be a feature that 1. causes problems and 2. provides extremely minimal benefits. And what do we do with features that cause problems and provide extremely minimal benefits? We yank 'em.Nick Sabalausky wrote:A programming language *is* a set of enforced conventions. When something either can't be enforced mechanically (ex: accurate and meaningful variable names), or has real practical value in not having an enforced convention (ex: user-definable variable names, free-form whitespace, underscores in numeric literals), that's when it's left to the users to make up their own arbitrary and likely-conflicting conventions. Arbitrary freedoms just for the sake of it: great in real life, lousy in a programming language. If we don't enforce the convention of (non-property) functions being called with parens, the only things gained besides that useless "arbitrary freedom in a programming language just for the sake of it" is a couple fewer keystrokes and an extremely minuscule reduction in alleged "noise" (the usefulness of which is easily canceled out by the fact that reduction in inconsistency improves readability too)."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention.Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 29 2010
Nick Sabalausky wrote:A programming language *is* a set of enforced conventions. When something either can't be enforced mechanically (ex: accurate and meaningful variable names), or has real practical value in not having an enforced convention (ex: user-definable variable names, free-form whitespace, underscores in numeric literals), that's when it's left to the users to make up their own arbitrary and likely-conflicting conventions. Arbitrary freedoms just for the sake of it: great in real life, lousy in a programming language. If we don't enforce the convention of (non-property) functions being called with parens, the only things gained besides that useless "arbitrary freedom in a programming language just for the sake of it" is a couple fewer keystrokes and an extremely minuscule reduction in alleged "noise" (the usefulness of which is easily canceled out by the fact that reduction in inconsistency improves readability too).I agree. If we do not require parentheses on functions then there is no benefit to having property. I was on the side of not having a special "property" syntax. However the DIP4 example "ambiguous-looking code" was enough to make me happy to see Java... I've just been assuming properties have not yet been finished. And maybe we will get +=,-= in the future.
Jan 28 2010
On Thu, 28 Jan 2010 20:51:29 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Nick Sabalausky wrote:It forces a convention. The convention is important, almost as important as the name of the function. Think of it as an extension of the function name, like extra punctuation that changes the human interpretation of the function. It means you must be explicit what you intend, the parentheses become a detail that is important to the compiler. If we adopted a convention where you could do: int x, y; int z = x y; implying that x should be added to y, then that would certainly work. But what value does it add (no pun intended)? Did the user intend to add them, or did he just make a typo? The convention of requiring the operator forces you to create unambiguous code, just like requiring the parentheses forces you to declare your expectation of the function. -Steve"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention.Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 29 2010
Steven Schveighoffer wrote:On Thu, 28 Jan 2010 20:51:29 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It forces you to define a convention as vacuous and open to interpretation as any other. Not a quantum leap I reckon. AndreiNick Sabalausky wrote:It forces a convention."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtcbd$r0a$1 digitalmars.com...Unfortunately not. It forces nothing. That's my problem with the feature - it's nothing more than fostering a convention.Nick Sabalausky wrote:D's approach to properties *forces* functions to emulate fields.And yes, I already pointed out that would make it a no-argument function. And that's precisely my point. If we accept that it's bad to paint a car via its " property" wheel, then how can we possibly accept this to not be just as bad?: auto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 29 2010
Andrei Alexandrescu wrote:Nick Sabalausky wrote:Not really relevant, since the same applies to fields. auto car = new Car(); auto wheel = car.wheelFieldnotPropertyOrFunction; wheel.paintTheCar(); In this case, the wheel field contains a pointer back to the car. -- Rainer Deyke - rainerd eldwood.comauto car = new Car(); auto wheel = car.getWheel_ThisIsAFunctionNotAProperty(); wheel.paintTheCar();Because a function doesn't attempt to emulate a field.
Jan 29 2010
On 2010-01-28 17:27:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:The problem is not localized change. The result of stdin.byLine changes the _entire_ stdin.No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine; If you put it in a foreach loop, then it has an effect. But it's foreach that has the effect of calling popFront on the byLine view of stdin. Getting byLine by itself doesn't do anything. Another term I'd use for a property, perhaps a better one, is an 'accessor'. A property, or an accessor, gives you access to an aspect of the object you're dealing with. In the case above, you get access to stdin line by line. Getting access to something might allow you to modify it, or it may not, depending on what it is exactly. But just getting access to it doesn't modify the object in itself. Sorry to arrive late in this conversation. Let me address some other points: I know not everyone get it right all the time. But that's not necessarily a contradiction, it just means that the concept isn't really well understood. If there was a good definition for it from an authoritative reference, it might help reduce the confusion. Currently the only authoritative element seems to be the syntax, no wonder it's confusing. Andrei, you keep complaining it's a convention. It *is* a convention, because only a convention can differentiate actions from accessors. Ideally, we wouldn't need a special syntax: English words would be enough. But as you know English words alone are often ambiguous. Either the convention is (1) how we name things -- like isEmpty vs. empty -- but I think you don't like that. Either it's (2) a syntactic convention -- empty vs. empty() -- but then the meaning becomes a little more subtle. Or (3) you can give the same meaning to both empty and empty(), but then people are left to guess what it means (action or accessor), and it creates incongruities with callables. Or (4) you can force empty() to always be with parenthesis and let people guess what it means; at least you don't have incongruities. There's no perfect solution. But of all of these options, the one used in D1 (number 3) has the most drawbacks: you can't distinguish actions from accessors, and on top of that you have problems with returning callables. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 28 2010
On 01/29/2010 05:48 AM, Michel Fortin wrote:No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine;It reads a line off stdin. Try it.
Jan 29 2010
On 2010-01-29 06:25:44 -0500, Pelle Månsson <pelle.mansson gmail.com> said:On 01/29/2010 05:48 AM, Michel Fortin wrote:Ah, I see, you're right. Silly me for not trying. So it's not an accessor after all. The problem is that, even disregarding the property syntax, the name strongly suggests it's an accessor, but it has side effects, which it shouldn't. Either we change the name to something else, like 'consumeLines()', or we make it behave like an accessor. I'd go for the second option. The basic problem lies in the very basic definition of an input range. Due to its interface (popFront + front), an input range is forced to consume the its first element by its mere existence. I think constructing an input range shouldn't have side effects. It should be more symmetrical with an output range. It could have just one function, 'take' to get the next element, and now byLine could work correctly. -- Michel Fortin michel.fortin michelf.com http://michelf.com/No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine;It reads a line off stdin. Try it.
Jan 29 2010
On Fri, 29 Jan 2010 08:03:13 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 06:25:44 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> said:Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :) The truth is, the fact that byLine modifies stdin by its mere existence proves to be inconsequential. Nobody will fetch the byLine property without using it. It's still an accessor. -SteveOn 01/29/2010 05:48 AM, Michel Fortin wrote:Ah, I see, you're right. Silly me for not trying. So it's not an accessor after all. The problem is that, even disregarding the property syntax, the name strongly suggests it's an accessor, but it has side effects, which it shouldn't. Either we change the name to something else, like 'consumeLines()', or we make it behave like an accessor. I'd go for the second option. The basic problem lies in the very basic definition of an input range. Due to its interface (popFront + front), an input range is forced to consume the its first element by its mere existence. I think constructing an input range shouldn't have side effects. It should be more symmetrical with an output range. It could have just one function, 'take' to get the next element, and now byLine could work correctly.No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine;It reads a line off stdin. Try it.
Jan 29 2010
On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)The truth is, the fact that byLine modifies stdin by its mere existence proves to be inconsequential. Nobody will fetch the byLine property without using it. It's still an accessor.That's only true if you use byLine exclusively. Here is a case where the advance fetching of byLine could go wrong: // fetch 3 lines: string[] consume(3, stdin.byLine); // now fill a buffer ubyte[] buffer; buffer = stdin.rawRead(buffer); E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); } return elements; } The problem here is that the consume() function will in reality consume 4 lines of stdin, even though it just take 3 from byLine. When we later call rawRead, a line has been lost. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
On Fri, 29 Jan 2010 09:34:25 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I agree.Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done.I'm starting to think Anrei likes ambiguous semantics. :-)Yeah, I am on your side. byLine has some nuances that make it incompatible with other uses of the stream. In fact, byLine might only be useful in processing the entire file. Hm... opApply? -SteveThe truth is, the fact that byLine modifies stdin by its mere existence proves to be inconsequential. Nobody will fetch the byLine property without using it. It's still an accessor.That's only true if you use byLine exclusively. Here is a case where the advance fetching of byLine could go wrong: // fetch 3 lines: string[] consume(3, stdin.byLine); // now fill a buffer ubyte[] buffer; buffer = stdin.rawRead(buffer); E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); } return elements; } The problem here is that the consume() function will in reality consume 4 lines of stdin, even though it just take 3 from byLine. When we later call rawRead, a line has been lost.
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.) The fact we're having a debate about this (and Steve even says it's a clear cut case and there are other more ambiguous!) is worrisome. Take this: I got different answers from _supporters_ of property! A good convention is one that you apply without wasting time to think of it every single time you use it: naming conventions, braces conventions, even most class vs. struct conventions. The well-defined ones work great because _they save you time_. This property stuff doesn't save anyone time (the provider is aggravated and the client is aggravated too). Honest, I think it's quite a misfeature. If there's a possibility to fix the ambiguities of the old system, I'd kick property into oblivion today. We need digitalmars.D.is_it_a_property_or_not. Whenever in doubt, people can ask a question there. AndreiHey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)
Jan 29 2010
On Fri, 29 Jan 2010 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Michel Fortin wrote:It's been mentioned before that tough decisions need to be made in many areas of programming. Deciding what is a property and what is not is no different. Using byLine as the strawman does not disprove the usefulness of properties.On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.)Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)The fact we're having a debate about this (and Steve even says it's a clear cut case and there are other more ambiguous!) is worrisome. Take this: I got different answers from _supporters_ of property!Again, property cannot provide an intuitive solution for everything, just like ranges cannot solve everything.A good convention is one that you apply without wasting time to think of it every single time you use it: naming conventions, braces conventions, even most class vs. struct conventions. The well-defined ones work great because _they save you time_. This property stuff doesn't save anyone time (the provider is aggravated and the client is aggravated too). Honest, I think it's quite a misfeature. If there's a possibility to fix the ambiguities of the old system, I'd kick property into oblivion today.The only one you stated here that is on par with property is naming conventions. They don't save you time writing code, they save you time *reading* code. The work goes into the writing (how to name this properly? How to make the name intuitive?) and then when reading, it comes natural. Without property you lose part of that concept. The parentheses are an extension of the symbol name, defined by the author, nothing more. What this *means* is up to you. In fact, properties *are* an extension of naming conventions.We need digitalmars.D.is_it_a_property_or_not. Whenever in doubt, people can ask a question there.OK: digitalmars.d.should_this_be_a_class_or_struct. digitalmars.d.should_this_symbol_be_capitalized. digitalmars.d.should_this_use_a_function_pointer_or_delegate. digitalmars.d.should_this_be_const_or_immutable. Can we ever get any work done without these? -Steve
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Except it has no reward associated with it. AndreiMichel Fortin wrote:It's been mentioned before that tough decisions need to be made in many areas of programming. Deciding what is a property and what is not is no different.On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.)Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)
Jan 29 2010
On Fri, 29 Jan 2010 11:17:04 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Clarity. Disambiguation. All the rewards that come from other naming conventions. Sorry you don't see it that way. -SteveOn Fri, 29 Jan 2010 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Except it has no reward associated with it.Michel Fortin wrote:It's been mentioned before that tough decisions need to be made in many areas of programming. Deciding what is a property and what is not is no different.On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.)Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 11:17:04 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter? AndreiSteven Schveighoffer wrote:Clarity. Disambiguation. All the rewards that come from other naming conventions. Sorry you don't see it that way.On Fri, 29 Jan 2010 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Except it has no reward associated with it.Michel Fortin wrote:It's been mentioned before that tough decisions need to be made in many areas of programming. Deciding what is a property and what is not is no different.On 2010-01-29 08:18:46 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.)Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)Andrei is the one who complained that it's difficult to know whether 'byLine' is a property in the first place. I'm just explaining why it is, and what should be done. I'm starting to think Anrei likes ambiguous semantics. :-)
Jan 29 2010
On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved. AndreiHow is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
On Fri, 29 Jan 2010 11:29:22 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:I think we all agree that setters the way D1 does them are very prone to abuse. So all that is left is no-argument functions. There are other alternative conventions to what you stated. This is my convention: * use property where the main purpose of the function is to fetch a value (computed or not, modifying the container or not) There are others mentioned in this thread. A property convention is useful to readers of the code. The existence of the property feature makes it *possible* to define conventions -- it doesn't define a convention itself. -SteveOn Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 11:29:22 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision. AndreiSteven Schveighoffer wrote:I think we all agree that setters the way D1 does them are very prone to abuse. So all that is left is no-argument functions. There are other alternative conventions to what you stated. This is my convention: * use property where the main purpose of the function is to fetch a value (computed or not, modifying the container or not)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:is pop's main purpose to fetch a value or to modify the stack? I'd say the purpose is split equally, so it's not a function whose main purpose is to fetch a value. I admit this is a good example where a judgement call comes into play, but we aren't all robots obeying every rule literally. There are sometimes exceptions in conventions, or at least the rule is subject to interpretation. -SteveOn Fri, 29 Jan 2010 11:29:22 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision.Steven Schveighoffer wrote:I think we all agree that setters the way D1 does them are very prone to abuse. So all that is left is no-argument functions. There are other alternative conventions to what you stated. This is my convention: * use property where the main purpose of the function is to fetch a value (computed or not, modifying the container or not)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:So now we're down to proportions, nuance, and where "main" goes. You made my point. I win.Steven Schveighoffer wrote:is pop's main purpose to fetch a value or to modify the stack? I'd say the purpose is split equally, so it's not a function whose main purpose is to fetch a value.On Fri, 29 Jan 2010 11:29:22 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision.Steven Schveighoffer wrote:I think we all agree that setters the way D1 does them are very prone to abuse. So all that is left is no-argument functions. There are other alternative conventions to what you stated. This is my convention: * use property where the main purpose of the function is to fetch a value (computed or not, modifying the container or not)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -SteveI admit this is a good example where a judgement call comes into play, but we aren't all robots obeying every rule literally.If that's not enough, I have many others. With braces or names, I obey rules literally without any trouble. The problem with property is, there are too many exceptions, judgment calls, and edge cases.There are sometimes exceptions in conventions, or at least the rule is subject to interpretation.Which brings home my point: the entire business of deciding property or not is a waste of everyone's time. There's no simple rule, and there's no advantage to be gained after having made the decision one way or another. Andrei
Jan 29 2010
On Fri, 29 Jan 2010 12:56:43 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:So now we're down to proportions, nuance, and where "main" goes. You made my point. I win.You just don't get it. declaring property or not is part of naming the function. Any naming convention either can have strict rules or not. You cited two very strict naming conventions, I cited a not-so-strict one, one that is open to interpretation. A similar naming convention in Java is the "isX" being a boolean property. Well, that doesn't always work because english doesn't always follow strict rules. Same thing for properties. I don't know what you think you've won. I never said properties make every possible function name intuitive.We went through scores of threads dissecting the names for range methods and what they should be. Does that mean that ranges are useless because we had to waste so much time naming their functions? The fact that we are arguing over one stupid function for this long is mind-boggling. Drop the straw man and look at the big picture. MOST OF THE TIME it is useful and intuitive. If that's not worth anything to you, then I don't know what else to say.I admit this is a good example where a judgement call comes into play, but we aren't all robots obeying every rule literally.If that's not enough, I have many others. With braces or names, I obey rules literally without any trouble. The problem with property is, there are too many exceptions, judgment calls, and edge cases.No, there is no simple rule, just like there's no simple rule for symbol names. If you spend the time to name your properties correctly, the intuition provided saves all your users from wasting time looking up the documentation. It saves reviewers from wasting time looking up documentation to understand what a coder is doing. It's not a waste of time if it has benefits, and it does. You just refuse to believe it. -SteveThere are sometimes exceptions in conventions, or at least the rule is subject to interpretation.Which brings home my point: the entire business of deciding property or not is a waste of everyone's time. There's no simple rule, and there's no advantage to be gained after having made the decision one way or another.
Jan 29 2010
On 2010-01-29 12:56:43 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Steven Schveighoffer wrote:You win because Steven's definition is not good enough. I said before that we should have a authoritative definition. If we really can't define how a property should be defined after some reflection, then you really win. My definition is that a property gives access to an aspect of an object and doesn't modify it (the getter is essentially logical-const). In this case, 'pop' doesn't give you access to something in the stack, it removes an element (that's an action) and give you the element. It's pretty clear that 'pop' is used as a verb here, that should be enough to decide it's a function. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:So now we're down to proportions, nuance, and where "main" goes. You made my point. I win.Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision.is pop's main purpose to fetch a value or to modify the stack? I'd say the purpose is split equally, so it's not a function whose main purpose is to fetch a value.
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 12:56:43 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Ok this makes sense. So something is a property if fetching it doesn't mess up the parent object. (Maybe properties should be pure even.) The lingering question is whether you can later use the fetched property to operate change in the parent object. I guess that it's reasonable to leave that up to the person defining the object and its property. I guess that's a set of rules that is simple, borderline meaningful, and easy to follow. By that logic File.byLine is a property, Stack.pop() is a function, Stack.top and Stack.empty are properties etc. That being said, I agree with Pelle that actions invoked without parens are darn attractive. AndreiSteven Schveighoffer wrote:You win because Steven's definition is not good enough. I said before that we should have a authoritative definition. If we really can't define how a property should be defined after some reflection, then you really win. My definition is that a property gives access to an aspect of an object and doesn't modify it (the getter is essentially logical-const).On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:So now we're down to proportions, nuance, and where "main" goes. You made my point. I win.Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision.is pop's main purpose to fetch a value or to modify the stack? I'd say the purpose is split equally, so it's not a function whose main purpose is to fetch a value.
Jan 29 2010
On Fri, 29 Jan 2010 13:52:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Michel Fortin wrote:No, because pure implies that the object must be immutable. They should be inout (if indeed they do not modify the object). But you have some problems there. Whether it logically modifies the object or not (I hate to use it, but byLine.front as proposed would have to not be inout) is subject to interpretation. I think it should not be a hard requirement, and at best should be expected to possibly mutate private state.My definition is that a property gives access to an aspect of an object and doesn't modify it (the getter is essentially logical-const).Ok this makes sense. So something is a property if fetching it doesn't mess up the parent object. (Maybe properties should be pure even.)The lingering question is whether you can later use the fetched property to operate change in the parent object. I guess that it's reasonable to leave that up to the person defining the object and its property.It isn't any different than using a field to modify the parent's state. Not modifying the parent's state is simply not in the charter for properties. It's too strict, and doesn't follow the abilities of that which it is modeled after.That being said, I agree with Pelle that actions invoked without parens are darn attractive.To each his own. I find them unclean and ambiguous. -Steve
Jan 29 2010
On 2010-01-29 13:52:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Ok this makes sense. So something is a property if fetching it doesn't mess up the parent object. (Maybe properties should be pure even.)Logical-pure, to be precise. ;-)The lingering question is whether you can later use the fetched property to operate change in the parent object. I guess that it's reasonable to leave that up to the person defining the object and its property.You can already do that with fields, so it make sense you can with properties too: class A { B b; } struct B { int c; } A a; a.b.c = 1; // works!I guess that's a set of rules that is simple, borderline meaningful, and easy to follow. By that logic File.byLine is a property, Stack.pop() is a function, Stack.top and Stack.empty are properties etc. That being said, I agree with Pelle that actions invoked without parens are darn attractive.And I agree too, they're attractive. But in a programming language I prefer to deal with less ambiguities even if it means a few more parenthesis. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
On Fri, 29 Jan 2010 13:41:43 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 12:56:43 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Be careful here, don't give Andrei hard criteria for declaring victory ;) But my larger point was that convention is convention, whether you use parentheses to designate what a function does, or the symbol name itself. Deciding the convention is liable to suit some and not others. Some people hate the flat terse names of Phobos' modules. Does that mean those people are wrong? Does that mean Walter and Andrei are wrong? The only thing that is wrong here is deciding there is exactly one right rigid way to designate what should and should not be a property. I think we should have a definition of property convention for Phobos, but I don't think it needs to be the *only* way people use properties in their own projects. In fact, it can't be because there is no english (or whatever language you use) interpreter in the compiler. -SteveSteven Schveighoffer wrote:You win because Steven's definition is not good enough. I said before that we should have a authoritative definition. If we really can't define how a property should be defined after some reflection, then you really win.On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:So now we're down to proportions, nuance, and where "main" goes. You made my point. I win.Consider: struct Stack(T) { T pop(); ... } By your definition, pop() should be a property. It doesn't quite strike me as an intuitive decision.is pop's main purpose to fetch a value or to modify the stack? I'd say the purpose is split equally, so it's not a function whose main purpose is to fetch a value.
Jan 29 2010
On 2010-01-29 13:57:06 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:"some reflection" is a hard criteria now? :-)You win because Steven's definition is not good enough. I said before that we should have a authoritative definition. If we really can't define how a property should be defined after some reflection, then you really win.Be careful here, don't give Andrei hard criteria for declaring victory ;)But my larger point was that convention is convention, whether you use parentheses to designate what a function does, or the symbol name itself. Deciding the convention is liable to suit some and not others. Some people hate the flat terse names of Phobos' modules. Does that mean those people are wrong? Does that mean Walter and Andrei are wrong? The only thing that is wrong here is deciding there is exactly one right rigid way to designate what should and should not be a property.Andrei wanted a good enough guideline so I gave one to him. We need a guideline if we hope for some consistency. Hopefully this guideline will be used through Phobos and this will set the example.I think we should have a definition of property convention for Phobos, but I don't think it needs to be the *only* way people use properties in their own projects. In fact, it can't be because there is no english (or whatever language you use) interpreter in the compiler.If someone want to diverge from the guideline, then that's his choice. It's pretty much like operator overloading: you can use it the intended way, or you can build boost::spirit. It's not like the compiler will ever be able to enforce this kind of thing, so there'll always be room for abuse, if you feel like it. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
On Fri, Jan 29, 2010 at 10:41 AM, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 12:56:43 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:eSteven Schveighoffer wrote:On Fri, 29 Jan 2010 12:23:24 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Consider: struct Stack(T) { =A0 =A0 T pop(); =A0 =A0 ... } By your definition, pop() should be a property. It doesn't quite strik=ayme as an intuitive decision.is pop's main purpose to fetch a value or to modify the stack? =A0I'd s=isthe purpose is split equally, so it's not a function whose main purpose=eto fetch a value.So now we're down to proportions, nuance, and where "main" goes. You mad=tmy point. I win.You win because Steven's definition is not good enough. I said before tha=we should have a authoritative definition. If we really can't define how =aproperty should be defined after some reflection, then you really win. My definition is that a property gives access to an aspect of an object a=nddoesn't modify it (the getter is essentially logical-const). In this case=,'pop' doesn't give you access to something in the stack, it removes an element (that's an action) and give you the element. It's pretty clear th=at'pop' is used as a verb here, that should be enough to decide it's a function.One more example to consider: RNG.randomInt() or RNG.randomInt I think Steven is right that you can always find corner cases, but that the existence of corner cases is pretty irrelevant. --bb
Jan 29 2010
Bill Baxter wrote:One more example to consider: RNG.randomInt() or RNG.randomInt I think Steven is right that you can always find corner cases, but that the existence of corner cases is pretty irrelevant.I agree. It's not the existence of corner cases I'm worried about, it's the frequency. Andrei
Jan 29 2010
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Ary Borenszweig wrote:Andrei Alexandrescu wrote:Correct. Just that I fear that it's a bit late for this all. It is disheartening enough that Walter got convinced by the past discussion and introduced property without much design - after a FAILED vote no less. I strongly believe a better solution is available, but everyone wanted the feature so the feature just got born. FWIW, my take for issues like the above: if a function returns a function or a delegate, it can't avail itself of automatic invocation of "()". That takes care of a corner case and keeps the mainstream case in good shape. I am not sure of a good solution for problems like writeln = 2; AndreiSteven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
On 01/29/2010 06:19 PM, Andrei Alexandrescu wrote:Ary Borenszweig wrote:How about property? When you add a property to a function it can be called as an assignment. property does not touch the calling of no-argument functions. Are there any problems with that?Andrei Alexandrescu wrote:Correct. Just that I fear that it's a bit late for this all. It is disheartening enough that Walter got convinced by the past discussion and introduced property without much design - after a FAILED vote no less. I strongly believe a better solution is available, but everyone wanted the feature so the feature just got born. FWIW, my take for issues like the above: if a function returns a function or a delegate, it can't avail itself of automatic invocation of "()". That takes care of a corner case and keeps the mainstream case in good shape. I am not sure of a good solution for problems like writeln = 2; AndreiSteven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Pelle MÃ¥nsson wrote:On 01/29/2010 06:19 PM, Andrei Alexandrescu wrote:Such a " property is just for the writing" design will leave property adepts very unhappy, I think. Even I admit that such a rule will be very inconsistent, albeit workable. AndreiAry Borenszweig wrote:How about property? When you add a property to a function it can be called as an assignment. property does not touch the calling of no-argument functions. Are there any problems with that?Andrei Alexandrescu wrote:Correct. Just that I fear that it's a bit late for this all. It is disheartening enough that Walter got convinced by the past discussion and introduced property without much design - after a FAILED vote no less. I strongly believe a better solution is available, but everyone wanted the feature so the feature just got born. FWIW, my take for issues like the above: if a function returns a function or a delegate, it can't avail itself of automatic invocation of "()". That takes care of a corner case and keeps the mainstream case in good shape. I am not sure of a good solution for problems like writeln = 2; AndreiSteven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
On 01/29/2010 07:01 PM, Andrei Alexandrescu wrote: ...It's not inconsistent, at most just a bit confusing on the call site. What property does is still very clear: - same syntax as fields for zero and one parameter functions - function call syntax *not* ok - mangled differently and recognizable by ide's (think gui programmming and ui design tools) and documentation tools. Probably also for metaprogramming. Additionally at the call site you can choose to drop parens for zero argument functions, author of those functions has no control over that. This feature is now orthogonal to property and may or may not end up in style guidelines. It's also one of those things a smart IDE could help you with (did the author really want this to be a property or not?) I think that solves most of the issues property was designed for.How about property? When you add a property to a function it can be called as an assignment. property does not touch the calling of no-argument functions. Are there any problems with that?Such a " property is just for the writing" design will leave property adepts very unhappy, I think. Even I admit that such a rule will be very inconsistent, albeit workable. Andrei
Jan 29 2010
Andrei Alexandrescu wrote:Ary Borenszweig wrote:I think at least for the function/delegate problem, requiring () to invoke it might be good. int foo() { ... } auto dg1 = bool function() { ... }; auto x = dg1; // x is bool function() auto y = dg1(); // y is bool auto dg2 = &foo; auto z = dg2; // z is int function() auto w = dg2(); // z is int The only thing that remains "problematic" is this one: auto dg3 = foo; // It's int. To take the address use & // but might lead to unexpected results // when using "auto"Andrei Alexandrescu wrote:Correct. Just that I fear that it's a bit late for this all. It is disheartening enough that Walter got convinced by the past discussion and introduced property without much design - after a FAILED vote no less. I strongly believe a better solution is available, but everyone wanted the feature so the feature just got born. FWIW, my take for issues like the above: if a function returns a function or a delegate, it can't avail itself of automatic invocation of "()". That takes care of a corner case and keeps the mainstream case in good shape. I am not sure of a good solution for problems like writeln = 2;Steven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
On 01/29/2010 07:23 PM, Ary Borenszweig wrote:Andrei Alexandrescu wrote:If () is required to invoke delegates, that isn't a problem. First use will tell on it.Ary Borenszweig wrote:I think at least for the function/delegate problem, requiring () to invoke it might be good. int foo() { ... } auto dg1 = bool function() { ... }; auto x = dg1; // x is bool function() auto y = dg1(); // y is bool auto dg2 = &foo; auto z = dg2; // z is int function() auto w = dg2(); // z is int The only thing that remains "problematic" is this one: auto dg3 = foo; // It's int. To take the address use & // but might lead to unexpected results // when using "auto"Andrei Alexandrescu wrote:Correct. Just that I fear that it's a bit late for this all. It is disheartening enough that Walter got convinced by the past discussion and introduced property without much design - after a FAILED vote no less. I strongly believe a better solution is available, but everyone wanted the feature so the feature just got born. FWIW, my take for issues like the above: if a function returns a function or a delegate, it can't avail itself of automatic invocation of "()". That takes care of a corner case and keeps the mainstream case in good shape. I am not sure of a good solution for problems like writeln = 2;Steven Schveighoffer wrote:The first post of this thread was about not invoking a function when you don't want it to be invoked. bearophile was doing: auto dg = int function() { ... }; return dg; but he wanted to return a reference to dg, not the result of invoking it. One way to prevent that is to never invoke functions unless they are marked with property. Or maybe functions defined like that (closures, whatever) should always require () to be invoked. If that doesn't sound reasonable, see this: auto dg1 = int function() { ... }; auto dg2 = dg1; I'd expect dg2's type to be dg1's type. Let's just think a solution to this problem first. :-)On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved.How is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:Unless you assume no global state, nullary functions are just a figment of your imagination. JustinOn Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved. AndreiHow is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Justin Johansson wrote:Andrei Alexandrescu wrote:Huh? What? Is there an extra "no"? AndreiSteven Schveighoffer wrote:Unless you assume no global state, nullary functions are just a figment of your imagination.On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved. AndreiHow is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Andrei Alexandrescu wrote:Justin Johansson wrote:No, correct as I meant it. Confusion arises depending on whether you have a syntactic or semantic definition of "nullary" and / or FP or non-FP viewpoint. Some would argue that a simple writeln() function is a nullary function. Syntactically it is but there is a hidden argument, namely stdout. So writeln() is semantically non-nullary and may even be thought of as being declared by way of a macro expanded as fwriteln( FILE* fp = stdout). So unless the assumption is that there is no global state (including stdout in this case), thinking of writeln() as a nullary function is just a figment of one's imagination (imho) :-) It's a unary function with a default argument = stdout ! In the general case of a function, foo, taking N arguments where each argument is declared with a default value, e.g. foo( int a1 = 3, int a2 = 5, .. int aN = whatever), then called using all defaults as by foo(), or even just foo if optional dropping () is allowed, would people still argue that foo() with all default args is a nullary function? Just my two cents on nullary. -- JustinAndrei Alexandrescu wrote:Huh? What? Is there an extra "no"? AndreiSteven Schveighoffer wrote:Unless you assume no global state, nullary functions are just a figment of your imagination.On Fri, 29 Jan 2010 11:21:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What I meant to say is that in the property landscape the following two conventions become suddenly attractive: * Do not use property at all * Use property for all nullary functions And they're bound to save a lot of time to everyone involved. AndreiHow is f.byLine clearer and less ambiguous than f.byLine()? Or vice versa for that matter?Note that properties can be named things other than byLine. -Steve
Jan 29 2010
Steven Schveighoffer wrote:Closer to the mark would be ... digitalmars.d1.dont_ask digitalmars.d2.should_this_be_a_class_or_struct digitalmars.d2.should_this_symbol_be_capitalized digitalmars.d2.should_this_use_a_function_pointer_or_delegate digitalmars.d2.should_this_be_const_or_immutable digitalmars.d2.will_shared_ever_work JustinWe need digitalmars.D.is_it_a_property_or_not. Whenever in doubt, people can ask a question there.OK: digitalmars.d.should_this_be_a_class_or_struct. digitalmars.d.should_this_symbol_be_capitalized. digitalmars.d.should_this_use_a_function_pointer_or_delegate. digitalmars.d.should_this_be_const_or_immutable. Can we ever get any work done without these? -Steve
Jan 29 2010
On 2010-01-29 11:47:17 -0500, Justin Johansson <no spam.com> said:Closer to the mark would be ... digitalmars.d1.dont_ask digitalmars.d2.should_this_be_a_class_or_struct digitalmars.d2.should_this_symbol_be_capitalized digitalmars.d2.should_this_use_a_function_pointer_or_delegate digitalmars.d2.should_this_be_const_or_immutable digitalmars.d2.will_shared_ever_work JustinAlso digitalmars.d.should_we_make_a_new_forum_for_this -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 11:47:17 -0500, Justin Johansson <no spam.com> said:We could just join in over at scala.org.what_is_the_difference_between_var_val_and_def_keywords bit the ensuring discussion would not be as friendly. JustinCloser to the mark would be ... digitalmars.d1.dont_ask digitalmars.d2.should_this_be_a_class_or_struct digitalmars.d2.should_this_symbol_be_capitalized digitalmars.d2.should_this_use_a_function_pointer_or_delegate digitalmars.d2.should_this_be_const_or_immutable digitalmars.d2.will_shared_ever_work JustinAlso digitalmars.d.should_we_make_a_new_forum_for_this
Jan 29 2010
On 2010-01-29 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:I'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.) The fact we're having a debate about this (and Steve even says it's a clear cut case and there are other more ambiguous!) is worrisome. Take this: I got different answers from _supporters_ of property!The problem entirely reside on the ambiguous semantics of 'byLine'. The name makes us think it does something while it does something else (consuming a line). If it did what we'd expect it should be a property, but since it does not it shouldn't be. Fix 'byLine', either by changing the name or changing what it does, and whether it's a property or not will become clear.A good convention is one that you apply without wasting time to think of it every single time you use it: naming conventions, braces conventions, even most class vs. struct conventions. The well-defined ones work great because _they save you time_.Well, you should probably care a little more about your naming convention. It's confusing, and it'll probably end up waisting the time of some people who'll wonder why it consumes lines before you read them. I was absolutely sure it didn't before someone pointed it out to me. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:That's an implementation problem of byLine, not a issue with the byLine name. AndreiI'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.) The fact we're having a debate about this (and Steve even says it's a clear cut case and there are other more ambiguous!) is worrisome. Take this: I got different answers from _supporters_ of property!The problem entirely reside on the ambiguous semantics of 'byLine'. The name makes us think it does something while it does something else (consuming a line). If it did what we'd expect it should be a property, but since it does not it shouldn't be. Fix 'byLine', either by changing the name or changing what it does, and whether it's a property or not will become clear.A good convention is one that you apply without wasting time to think of it every single time you use it: naming conventions, braces conventions, even most class vs. struct conventions. The well-defined ones work great because _they save you time_.Well, you should probably care a little more about your naming convention. It's confusing, and it'll probably end up waisting the time of some people who'll wonder why it consumes lines before you read them. I was absolutely sure it didn't before someone pointed it out to me.
Jan 29 2010
On 2010-01-29 11:19:32 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:That's an implementation problem of byLine, not a issue with the byLine name.Ok, so if you agree that 'byLine' eating a line on creation is a bug, that means you don't expect 'byLine' to eat a line. That makes 'byLine' a property since calling the accessor doesn't (theoretically) modify the underlying object, it just provides access to an aspect of that object. Now it seems Steven and I both agree that it's a property. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 10:40:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:This is a very good point! Using byLine as an argument against property is just silly, as it is badly-named to begin with. The name itself doesn't really tell you what it does, you have to read the docs or see it in the context of a foreach to understand it. The omittable parentheses are not the problem here. A more descriptive name would be either of these, depending on how the function actually works: readByLine() // not a property lines // definitely a property byLinesRange // also definitely a propertyI'll tell you what I'd have liked: a landslide of responses to my question revealing my mistaken ways and clarifying without a shade of a doubt that byLine should be a property. Or not. (I don't even care which.) The fact we're having a debate about this (and Steve even says it's a clear cut case and there are other more ambiguous!) is worrisome. Take this: I got different answers from _supporters_ of property!The problem entirely reside on the ambiguous semantics of 'byLine'. The name makes us think it does something while it does something else (consuming a line). If it did what we'd expect it should be a property, but since it does not it shouldn't be. Fix 'byLine', either by changing the name or changing what it does, and whether it's a property or not will become clear.Speaking of Andrei's naming convention; in the case of empty() there were a lot of protests to the name, because people couldn't tell whether it was a property or an action. The property annotation mends that. -LarsA good convention is one that you apply without wasting time to think of it every single time you use it: naming conventions, braces conventions, even most class vs. struct conventions. The well-defined ones work great because _they save you time_.Well, you should probably care a little more about your naming convention. It's confusing, and it'll probably end up waisting the time of some people who'll wonder why it consumes lines before you read them. I was absolutely sure it didn't before someone pointed it out to me.
Jan 29 2010
Andrei Alexandrescu wrote:We need digitalmars.D.is_it_a_property_or_not. Whenever in doubt, people can ask a question there. AndreiObviously that's a rhetorical suggestion by Andrei ... but maybe a good idea if all this silliness prevails. Justin
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 08:03:13 -0500, Michel Fortin <michel.fortin michelf.com> wrote:Which debate are you referring to?On 2010-01-29 06:25:44 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> said:Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)On 01/29/2010 05:48 AM, Michel Fortin wrote:Ah, I see, you're right. Silly me for not trying. So it's not an accessor after all. The problem is that, even disregarding the property syntax, the name strongly suggests it's an accessor, but it has side effects, which it shouldn't. Either we change the name to something else, like 'consumeLines()', or we make it behave like an accessor. I'd go for the second option. The basic problem lies in the very basic definition of an input range. Due to its interface (popFront + front), an input range is forced to consume the its first element by its mere existence. I think constructing an input range shouldn't have side effects. It should be more symmetrical with an output range. It could have just one function, 'take' to get the next element, and now byLine could work correctly.No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine;It reads a line off stdin. Try it.The truth is, the fact that byLine modifies stdin by its mere existence proves to be inconsequential. Nobody will fetch the byLine property without using it. It's still an accessor.Yah, though I agree it's nicer to not prime the line in the constructor. Andrei
Jan 29 2010
On Fri, 29 Jan 2010 10:31:28 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:hm... let me dig it up. (unwillingly) http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=90971On Fri, 29 Jan 2010 08:03:13 -0500, Michel Fortin <michel.fortin michelf.com> wrote:Which debate are you referring to?On 2010-01-29 06:25:44 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> said:Hey, it's that dead horse again, let's beat it! Andrei and I and several others discussed this ad infinitum. You will never convince Andrei that his design is wrong :)On 01/29/2010 05:48 AM, Michel Fortin wrote:Ah, I see, you're right. Silly me for not trying. So it's not an accessor after all. The problem is that, even disregarding the property syntax, the name strongly suggests it's an accessor, but it has side effects, which it shouldn't. Either we change the name to something else, like 'consumeLines()', or we make it behave like an accessor. I'd go for the second option. The basic problem lies in the very basic definition of an input range. Due to its interface (popFront + front), an input range is forced to consume the its first element by its mere existence. I think constructing an input range shouldn't have side effects. It should be more symmetrical with an output range. It could have just one function, 'take' to get the next element, and now byLine could work correctly.No. Calling byLine doesn't change the stream. It returns a different view of stdin, which can be used to modify the stream, or not. I think it should be a property. If it was 'getNextLine' then it should be a function. As a proof, this doesn't have any effect: stdin.byLine;It reads a line off stdin. Try it.This would help, but you still have to be careful with streamed ranges. The valid point Michael brought up is the following: // fetch 3 lines: string[] consume(3, stdin.byLine); // now fill a buffer ubyte[] buffer; buffer = stdin.rawRead(buffer); E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); } return elements; } Note the extra popFront. So the loop must be rewritten: if (count != 0) // base case, need special case for this { int i = 0; while(!range.empty) // he forgot this condition { elements ~= range.front; if(++i == count) break; range.popFront(); } } ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck. -SteveThe truth is, the fact that byLine modifies stdin by its mere existence proves to be inconsequential. Nobody will fetch the byLine property without using it. It's still an accessor.Yah, though I agree it's nicer to not prime the line in the constructor.
Jan 29 2010
On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
On Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it... -Steveugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
On 2010-01-29 11:00:31 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:On Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:Hum, well I used 'take' while you defined 'get' as the basic function for stream ranges. They're the same thing. Rename 'take' for 'get', or the reverse, and all input ranges can work with the same 'get' or 'take' function. (Note: I use 'take' instead of 'get' because it seems clearer to me that it also removes the element from the range.) -- Michel Fortin michel.fortin michelf.com http://michelf.com/On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it...ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
On Fri, 29 Jan 2010 11:08:37 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 11:00:31 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Oh, I get it now. Yes, you can define this (BTW, I agree take is better than get). Whether we will ever get x.fn() => fn(x) for ranges remains to be seen. Without that, you have boilerplate code in every forward range and beyond. The other possibility is to define an abstraction function like: E take(R, E)(ref R range) { static if(isForwardRange!(R)) { // repeat your code above } else return range.take(); } and then use take(r) whenever you need that capability. -SteveOn Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:Hum, well I used 'take' while you defined 'get' as the basic function for stream ranges. They're the same thing. Rename 'take' for 'get', or the reverse, and all input ranges can work with the same 'get' or 'take' function. (Note: I use 'take' instead of 'get' because it seems clearer to me that it also removes the element from the range.)On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it...ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:It should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag. AndreiOn 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it...ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
On Fri, 29 Jan 2010 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:That actually makes a lot of sense. I hope this fix goes in. -SteveOn Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:It should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it...ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:http://d.puremagic.com/issues/show_bug.cgi?id=3752 AndreiSteven Schveighoffer wrote:That actually makes a lot of sense. I hope this fix goes in.On Fri, 29 Jan 2010 10:53:50 -0500, Michel Fortin <michel.fortin michelf.com> wrote:It should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.On 2010-01-29 10:49:34 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:Except stream ranges. I don't get it...ugh... much simpler with a true stream-like range that supports what is natural for streams: for(int i = 0; i < count && !range.empty; i++) { elements ~= range.get(); } But of course, then this function doesn't work for other range types. I decided in that discussion long ago that stream ranges were going to suck.You can always define a generic take() like this: E take(R, E)(ref R range) { E element = range.front; range.popFront(); return element; } This will work for any forward range.
Jan 29 2010
On 2010-01-29 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:It should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.So now you want the front to fetch from stdin on the first call? It's the same problem as 'byLine' eating the first line when you create it: neither one or the other should affect the stream. Take my example from before: // fetch 3 lines: string[] consume(3, stdin.byLine); // now fill a buffer ubyte[] buffer; buffer = stdin.rawRead(buffer); E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); } return elements; } Now add a range.front just after the popFront(): E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); E peakedElement = range.front; } return elements; } And suddenly you'll get the same problem. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
On Fri, 29 Jan 2010 11:33:17 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-01-29 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:No, you're reaching here :) What Andrei is doing is acknowledging that front has already performed the job of popFront. Because of the nature of streams, you cannot get the data from the stream, and leave it on the stream at the same time. It's just not feasible. What the solution Andrei came up with does is to make stream ranges behave as close as possible to forward ranges. That small inconsistency will not hurt you because most of the time you are not calling front for an element you don't intend to use. And even within that paradigm, you are even less likely to use the stream in another capacity. In other words, as the last usage of a range in an algorithm function, this: r.front; r.popFront(); is way more likely than: r.popFront() r.front; -SteveIt should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.So now you want the front to fetch from stdin on the first call? It's the same problem as 'byLine' eating the first line when you create it: neither one or the other should affect the stream.
Jan 29 2010
On 2010-01-29 11:54:41 -0500, "Steven Schveighoffer" <schveiguy yahoo.com> said:On Fri, 29 Jan 2010 11:33:17 -0500, Michel Fortin <michel.fortin michelf.com> wrote:"will not hurt because most of the time"... surely you meant "will not hurt most of the time because". You're acknowledging it's an inconsistency and that it'll hurt.On 2010-01-29 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:No, you're reaching here :) What Andrei is doing is acknowledging that front has already performed the job of popFront. Because of the nature of streams, you cannot get the data from the stream, and leave it on the stream at the same time. It's just not feasible. What the solution Andrei came up with does is to make stream ranges behave as close as possible to forward ranges. That small inconsistency will not hurt you because most of the time you are not calling front for an element you don't intend to use. And even within that paradigm, you are even less likely to use the stream in another capacity.It should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.So now you want the front to fetch from stdin on the first call? It's the same problem as 'byLine' eating the first line when you create it: neither one or the other should affect the stream.In other words, as the last usage of a range in an algorithm function, this: r.front; r.popFront(); is way more likely than: r.popFront() r.front;Yeah, it's less likely to be a problem. But "less likely to be a problem" does still does not make things reliable. Something reliable works all the time, or it just doesn't work and tells you. And I'd argue that it's very likely that an algorithm hits the problem, check this: skipEmptyLines(stdin.byLine); string line = stdin.readln; void skipEmptyLines(R)(R range) { while (!range.empty && range.front == "") range.popFront; } skipEmptyLine works right with ranges, but not with a stream. On the last loop, it calls range.front, which removes a line from the stream, and then say it's finished. The truth is that this algorithm doesn't work with streams as it relies on a buffer being available. But it still compiles, silently introducing a bogus behaviour. If byLine defined only a 'take' function, we wouldn't have this problem as skipEmptyLines wouldn't compile, forcing you to use some kind of buffered stream or another algorithm that works correctly with streams. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Michel Fortin wrote:Yeah, it's less likely to be a problem. But "less likely to be a problem" does still does not make things reliable. Something reliable works all the time, or it just doesn't work and tells you.stream.front after stream.popFront works all the time and fetches a new line off the stream. Like Steve said, you can't at the same time fetch a line and leave it back in the stream. Andrei
Jan 29 2010
On 2010-01-29 12:21:18 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Michel Fortin wrote:The problem is that algorithms that depends on this will work with other ranges, but will fail silently when given a stream. In all seriousness, even Java streams are better modeled than this (although more limited by not having templates). The basic Java input stream doesn't have a 'front' byte, you can only read the next byte (or the few next bytes). If you need to rewind, there is a standard way, but most streams need to be wrapped in a buffered stream first to provide this capability. So in our case, if you need to add a one-byte or a one-line buffer for a filtering stream I think it should be done explicitly as it has side effects on the underlying stream. In Java you do this by composition, creating a buffered stream from another input stream when you need one. Doing this implicitly, and especially creating a separate buffer each time you create a new filtering range, is what makes the problem hard to follow. Making 'front' lazy fetching will help in many cases, but it'll never remove the problem entirely. -- Michel Fortin michel.fortin michelf.com http://michelf.com/Yeah, it's less likely to be a problem. But "less likely to be a problem" does still does not make things reliable. Something reliable works all the time, or it just doesn't work and tells you.stream.front after stream.popFront works all the time and fetches a new line off the stream. Like Steve said, you can't at the same time fetch a line and leave it back in the stream.
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 12:21:18 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:An algorithm can fail in many silent ways if it misuses the range interface. None of std.algorithm algorithms uses front naively.Michel Fortin wrote:The problem is that algorithms that depends on this will work with other ranges, but will fail silently when given a stream.Yeah, it's less likely to be a problem. But "less likely to be a problem" does still does not make things reliable. Something reliable works all the time, or it just doesn't work and tells you.stream.front after stream.popFront works all the time and fetches a new line off the stream. Like Steve said, you can't at the same time fetch a line and leave it back in the stream.In all seriousness, even Java streams are better modeled than this (although more limited by not having templates). The basic Java input stream doesn't have a 'front' byte, you can only read the next byte (or the few next bytes). If you need to rewind, there is a standard way, but most streams need to be wrapped in a buffered stream first to provide this capability.Can you run a basic algorithm on a Java stream and on an array as well? Andrei
Jan 29 2010
On 2010-01-29 12:53:27 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:An algorithm can fail in many silent ways if it misuses the range interface. None of std.algorithm algorithms uses front naively.Easy to say. How did you verify that? The problem is very subtle: if you call front after popFront on something like byLine which adds a buffer on top of another range, it'll eat one or more element on the downstream range that will be lost if you dispose of the filtering range. It won't have any effect on algorithms using the filtering range in itself, only on those using both the filtering range and the downstream range in tandem. So basically, if you have an algorithm that calls front after popFront, that algorithm cannot be used reliably for ranges filtering a stream when that stream is also used directly, or used via other filtering ranges. There's no way to enforce that as it becomes the user's problem. Whereas if input ranges only define 'take', it's pretty easy for the compiler to tell you an algorithm needs a buffer, so you add an intermediary buffer range yourself and you're now aware of the consequences.Can you run a basic algorithm on a Java stream and on an array as well?Java lacks templates, and thus lack compile-time duck typing and work only with bytes. But you could iterate on an array as if it was a stream: class ArrayStream { byte[] array; int pos; ArrayStream(byte[] array) { this.array = array; pos = 0; } int read() { if (pos > array.length) return -1; else return array[pos++]; } } I'm not trying to say that Java streams are superior to ranges, but they don't have unintended buffering issues. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 12:53:27 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:It's simply a mistake I make very seldom if at all (I don't remember any instance). The range interface is narrow, and algorithms are always careful with how they use it.An algorithm can fail in many silent ways if it misuses the range interface. None of std.algorithm algorithms uses front naively.Easy to say. How did you verify that?The problem is very subtle: if you call front after popFront on something like byLine which adds a buffer on top of another range, it'll eat one or more element on the downstream range that will be lost if you dispose of the filtering range. It won't have any effect on algorithms using the filtering range in itself, only on those using both the filtering range and the downstream range in tandem.Subtle problems could occur with a variety of other ranges if some algorithm messes them up.So basically, if you have an algorithm that calls front after popFront, that algorithm cannot be used reliably for ranges filtering a stream when that stream is also used directly, or used via other filtering ranges. There's no way to enforce that as it becomes the user's problem. Whereas if input ranges only define 'take', it's pretty easy for the compiler to tell you an algorithm needs a buffer, so you add an intermediary buffer range yourself and you're now aware of the consequences.I like take (I actually called it getNext). There was just too much aggravation in defining and using that interface. I've literally lost nights over figuring it out, and couldn't. Searching for getNext on this group will reveal some of the issues. Andrei
Jan 29 2010
Michel Fortin wrote:On 2010-01-29 11:18:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:I think this is not a problem as much as an organic characteristic of streams. STL's input streams work the same. AndreiIt should work for stream ranges if front() checks the "filled" flag and eats the next line if false, and popFront clears the "filled" flag.So now you want the front to fetch from stdin on the first call? It's the same problem as 'byLine' eating the first line when you create it: neither one or the other should affect the stream. Take my example from before: // fetch 3 lines: string[] consume(3, stdin.byLine); // now fill a buffer ubyte[] buffer; buffer = stdin.rawRead(buffer); E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); } return elements; } Now add a range.front just after the popFront(): E[] consume(E, R)(int count, R range) { E[] elements; foreach (i; 0..count) { elements ~= range.front; range.popFront(); E peakedElement = range.front; } return elements; } And suddenly you'll get the same problem.
Jan 29 2010
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:hjtpb4$1t17$1 digitalmars.com...Andrei, you keep complaining it's a convention. It *is* a convention, because only a convention can differentiate actions from accessors. Ideally, we wouldn't need a special syntax: English words would be enough. But as you know English words alone are often ambiguous.It's more than just the existence of ambiguous english words. It's also that () vs no-() makes it far easier to tell at a mere glance whether or not you're looking at a function. Imagine scrolling through a big chunk of code in a language that lacks optional-parens (and doesn't do any of that Java-style "getFoo()" crap). Without even reading a word of it, you quite literally *see* "function, function, value, value, etc." But with optional-parens (or those awful Java-style accessors), that gets thrown out the window and code needs more direct examination just to get the same amount of info out of it.
Jan 29 2010
Andrei Alexandrescu wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctly. property (or any other notation marking property getters/setters) should be enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property syntax to invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too. -- Michiel Helvensteijn
Jan 28 2010
On 01/28/2010 11:23 PM, Michiel Helvensteijn wrote:Andrei Alexandrescu wrote:I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctly. property (or any other notation marking property getters/setters) should be enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property syntax to invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too.
Jan 28 2010
Pelle MÃ¥nsson wrote:On 01/28/2010 11:23 PM, Michiel Helvensteijn wrote:++ AndreiAndrei Alexandrescu wrote:I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctly. property (or any other notation marking property getters/setters) should be enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property syntax to invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too.
Jan 28 2010
On Thu, Jan 28, 2010 at 2:49 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Pelle M=E5nsson wrote:y.On 01/28/2010 11:23 PM, Michiel Helvensteijn wrote:Andrei Alexandrescu wrote:I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctl=ldproperty (or any other notation marking property getters/setters) shou=axbe enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property synt=upto invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too.I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes =hishis own rules about which functions are property and which are not. If t=The "what" is the things listed in DIP4 (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4) Particularly these issues: int delegate() foo() { return delegate int(){ return 5; }; } // Is this an int or a delegate? auto x =3D foo(); // Is this a reference to foo, or a reference to the delegate returned by f= oo? auto y =3D &foo; --bbis somehow enforced, it will become a guessing game about how to call no-argument functions. For what?
Jan 28 2010
On 01/29/2010 12:01 AM, Bill Baxter wrote:On Thu, Jan 28, 2010 at 2:49 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:A delegate. Same as auto x = foo;Pelle M�nsson wrote:The "what" is the things listed in DIP4 (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4) Particularly these issues: int delegate() foo() { return delegate int(){ return 5; }; } // Is this an int or a delegate? auto x = foo();On 01/28/2010 11:23 PM, Michiel Helvensteijn wrote:Andrei Alexandrescu wrote:I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctly. property (or any other notation marking property getters/setters) should be enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property syntax to invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too.// Is this a reference to foo, or a reference to the delegate returned by foo? auto y =&foo;A reference to foo. I feel this is obvious. Maybe I am wrong.
Jan 29 2010
"Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjt46j$5qt$1 digitalmars.com...I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?Class "Foo" has member "bar". Is "bar" a member variable or a member function? Can you set it? Does it require arguments? You don't know, do you? It's a guessing game. To the caller, *properties are not functions*! I don't understand why we keep having to go in circles on this. They are data. Data, data, data. Not functions. Data. "Oh, but no, they're *implemented* as functions!" Who gives a crap? That's *implementation*. They're data. Data, data, data. With the proposal, if I use a class, that class has data and functions. Not "member variables, functions called with parens, and functions called without parens." Just data and functions. That's it. Data and functions. So if this is enforced, and you have a function, how do you call it? *With parens*! Why? Because it's a fucking function and functions are fucking something, you already know damn well if it's a function or data. Because if you don't know what the hell it is, you can't f***** make sensible use of it anyway.
Jan 28 2010
Nick Sabalausky wrote:"Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjt46j$5qt$1 digitalmars.com...Relax, we're all on the same boat. Unfortunately, your view that it's all functions and data is simplistic - it works well only when we talk about returning simple data types. I, too, wish it were that simple. AndreiI don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?Class "Foo" has member "bar". Is "bar" a member variable or a member function? Can you set it? Does it require arguments? You don't know, do you? It's a guessing game. To the caller, *properties are not functions*! I don't understand why we keep having to go in circles on this. They are data. Data, data, data. Not functions. Data. "Oh, but no, they're *implemented* as functions!" Who gives a crap? That's *implementation*. They're data. Data, data, data. With the proposal, if I use a class, that class has data and functions. Not "member variables, functions called with parens, and functions called without parens." Just data and functions. That's it. Data and functions. So if this is enforced, and you have a function, how do you call it? *With parens*! Why? Because it's a fucking function and functions are fucking something, you already know damn well if it's a function or data. Because if you don't know what the hell it is, you can't f***** make sensible use of it anyway.
Jan 28 2010
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:hjtbjh$pbg$1 digitalmars.com...Nick Sabalausky wrote:The only catches in the idea of the caller seeing it as all data and functions are issues that are equally true regardless of whether properites So ok, strictly speaking, there's functions and then there's data that comes in two flavors. But that still does absolutely nothing to change my point that removing optional parens creates *no* guessing game that we don't already have because it's still functions (use parens) and data (regardless of what type of data, don't use parens)."Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjt46j$5qt$1 digitalmars.com...Relax, we're all on the same boat. Unfortunately, your view that it's all functions and data is simplistic - it works well only when we talk about returning simple data types. I, too, wish it were that simple.I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?Class "Foo" has member "bar". Is "bar" a member variable or a member function? Can you set it? Does it require arguments? You don't know, do you? It's a guessing game. To the caller, *properties are not functions*! I don't understand why we keep having to go in circles on this. They are data. Data, data, data. Not functions. Data. "Oh, but no, they're *implemented* as functions!" Who gives a crap? That's *implementation*. They're data. Data, data, data. With the proposal, if I use a class, that class has data and functions. Not "member variables, functions called with parens, and functions called without parens." Just data and functions. That's it. Data and functions. So if this is enforced, and you have a function, how do you call it? *With parens*! Why? Because it's a fucking function and functions are to use something, you already know damn well if it's a function or data. Because if you don't know what the hell it is, you can't f***** make sensible use of it anyway.
Jan 28 2010
On 01/29/2010 02:21 AM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:hjtbjh$pbg$1 digitalmars.com...I don't think this definition really works. byLine returns a range, so it's data? If it's changed to an opApply based loop, is it still data? Where is the line between a simple function returning data and just data? I think property can be used to change the assignment, but not how the "get"-part of the function is called.Nick Sabalausky wrote:The only catches in the idea of the caller seeing it as all data and functions are issues that are equally true regardless of whether properites So ok, strictly speaking, there's functions and then there's data that comes in two flavors. But that still does absolutely nothing to change my point that removing optional parens creates *no* guessing game that we don't already have because it's still functions (use parens) and data (regardless of what type of data, don't use parens)."Pelle M�nsson"<pelle.mansson gmail.com> wrote in message news:hjt46j$5qt$1 digitalmars.com...Relax, we're all on the same boat. Unfortunately, your view that it's all functions and data is simplistic - it works well only when we talk about returning simple data types. I, too, wish it were that simple.I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?Class "Foo" has member "bar". Is "bar" a member variable or a member function? Can you set it? Does it require arguments? You don't know, do you? It's a guessing game. To the caller, *properties are not functions*! I don't understand why we keep having to go in circles on this. They are data. Data, data, data. Not functions. Data. "Oh, but no, they're *implemented* as functions!" Who gives a crap? That's *implementation*. They're data. Data, data, data. With the proposal, if I use a class, that class has data and functions. Not "member variables, functions called with parens, and functions called without parens." Just data and functions. That's it. Data and functions. So if this is enforced, and you have a function, how do you call it? *With parens*! Why? Because it's a fucking function and functions are to use something, you already know damn well if it's a function or data. Because if you don't know what the hell it is, you can't f***** make sensible use of it anyway.
Jan 29 2010
On Thu, 28 Jan 2010 17:54:33 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:On 01/28/2010 11:23 PM, Michiel Helvensteijn wrote:Just as every class designer makes up his own rules about naming functions. The parentheses are part of the name of a function. Whether in your view the parentheses have meaning or not is your opinion. But you should not be able to attach your own meaning to my functions. What if we allowed a feature where you could call functions with just an unambiguous prefix? so something like: stdin.by(); Is that ok with you? It's not unambiguous, is it just as easy to understand as using the full name? The fact that byLine is just as descriptive as byLine() makes no difference. It is not a quintessential example of ambiguity. It should be a property IMO because of what it does, but even if it's not, it's not ambiguous. There are other cases which are ambiguous. -SteveAndrei Alexandrescu wrote:I don't understand what any of this would improve. Is the byLine example less readable without the ()? Is it more bug prone? The only thing achieved as I can see is that every class designer makes up his own rules about which functions are property and which are not. If this is somehow enforced, it will become a guessing game about how to call no-argument functions. For what?I agree. So where's the consensus? Things seemed so clear when people were beaten with property over their head.If I read the TLP correctly, property seems not to be working correctly. property (or any other notation marking property getters/setters) should be enforced. Functions that have it must only be invoked using property syntax. Functions that don't have it must be called with parentheses. That's the whole point. To give the designer of the class control over how it is used. The problem is people blurring the line between what's supposed to be a function and what's supposed to be a property, by abusing property syntax to invoke actions without parentheses. In reality, I believe there's not only a clear line between the two intentions, there's a demilitarized zone. You just need to enforce it. You can't have your cake and eat it too.
Jan 29 2010
Michiel Helvensteijn wrote:Ah, my bad. I was guessing. Still, returning a handle from a property that can change the state of the originating object is.. iffy.I disagree. For example, I recently had to deal with tables. Each table has rows and columns. Removing a row removes a cell from each column. Removing a column removes a cell from each row. However, I wanted to deal with both the set of rows and the set of columns as generic sequences. My solution was something like this: struct Table { RowView rows(); ColumnView columns(); }; I think 'rows' and 'columns' are perfect candidates for properties. They are nouns, not verbs. They could reasonably be implemented as fields instead of functions. They are not actions. They are views into the containing Table. Aspects of the Table, if you will. Properties. -- Rainer Deyke - rainerd eldwood.com
Jan 29 2010
Michiel Helvensteijn wrote:Andrei Alexandrescu wrote:I agree, but I'll also note that I got contradictory opinions from different supporters of property. So now it looks all the more like a judgment call, which is exactly what I was worried in the first place.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story. A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging.Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -SteveOmitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes.I found my code to be more readable and just as predictable with the current rule. And it's not about two keystrokes, it's about persistent and ubiquitous syntactic noise. Gosh, property does suck. I was afraid that'd be true. Andrei
Jan 28 2010
On 01/28/2010 11:05 PM, Andrei Alexandrescu wrote:Michiel Helvensteijn wrote:Lot's of things are judgement calls, I don't see the problem. property is a tool like everything else, there are many more cases where it's pretty clear cut. The ambivalence here is inherent in the code, and only brought out by the property question, not caused by it. Notice there was also no consensus of what byLine actually did under the hood. Also, don't forget these: - property allows you to forbid the caller using parenthesis, there is no other way in D to achieve this for accessor functions - so far ignored in this thread: any kind of code inspection (reflection, compile time, by IDE) can use the ' property property' for various purposes.Andrei Alexandrescu wrote:I agree, but I'll also note that I got contradictory opinions from different supporters of property. So now it looks all the more like a judgment call, which is exactly what I was worried in the first place.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story. A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging.Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -SteveOmitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes.I found my code to be more readable and just as predictable with the current rule. And it's not about two keystrokes, it's about persistent and ubiquitous syntactic noise. Gosh, property does suck. I was afraid that'd be true. Andrei
Jan 28 2010
Lutger wrote:On 01/28/2010 11:05 PM, Andrei Alexandrescu wrote:Wise words. So how do I go about byLine? AndreiMichiel Helvensteijn wrote:Lot's of things are judgement calls, I don't see the problem. property is a tool like everything else, there are many more cases where it's pretty clear cut. The ambivalence here is inherent in the code, and only brought out by the property question, not caused by it. Notice there was also no consensus of what byLine actually did under the hood. Also, don't forget these: - property allows you to forbid the caller using parenthesis, there is no other way in D to achieve this for accessor functions - so far ignored in this thread: any kind of code inspection (reflection, compile time, by IDE) can use the ' property property' for various purposes.Andrei Alexandrescu wrote:I agree, but I'll also note that I got contradictory opinions from different supporters of property. So now it looks all the more like a judgment call, which is exactly what I was worried in the first place.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story. A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging.Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -SteveOmitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes.I found my code to be more readable and just as predictable with the current rule. And it's not about two keystrokes, it's about persistent and ubiquitous syntactic noise. Gosh, property does suck. I was afraid that'd be true. Andrei
Jan 28 2010
On 01/28/2010 11:28 PM, Andrei Alexandrescu wrote:Lutger wrote:You make a good judgement call :) this is possible right: auto iter = stdin.byLine; foreach(line; iter) ... could you imagine byLine as an abbreviation of byLineRange or getByLineRange a la Java? or even conceive of: stdin.byLine = aDifferentFlavorOfByLine? So yes, I'm inclined to think of it as a property.On 01/28/2010 11:05 PM, Andrei Alexandrescu wrote:Wise words. So how do I go about byLine? AndreiMichiel Helvensteijn wrote:Lot's of things are judgement calls, I don't see the problem. property is a tool like everything else, there are many more cases where it's pretty clear cut. The ambivalence here is inherent in the code, and only brought out by the property question, not caused by it. Notice there was also no consensus of what byLine actually did under the hood. Also, don't forget these: - property allows you to forbid the caller using parenthesis, there is no other way in D to achieve this for accessor functions - so far ignored in this thread: any kind of code inspection (reflection, compile time, by IDE) can use the ' property property' for various purposes.Andrei Alexandrescu wrote:I agree, but I'll also note that I got contradictory opinions from different supporters of property. So now it looks all the more like a judgment call, which is exactly what I was worried in the first place.byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story. A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging.Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -SteveOmitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes.I found my code to be more readable and just as predictable with the current rule. And it's not about two keystrokes, it's about persistent and ubiquitous syntactic noise. Gosh, property does suck. I was afraid that'd be true. Andrei
Jan 28 2010
On 28.01.2010 21:59, Andrei Alexandrescu wrote:How about this: foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?I'd say byLine as it's currently implemented in std.stdio is not a property. It initializes and returns a new ByLine struct each time it's called. It even has arguments that enables you to configure its return value differently each time you call it. Nowhere near how it would behave if it was a field. A property should at least return the same value if you call it several times in a row, without doing anything in between that you'd expect to alter the value. The fact that using byLine's return value changes the File itself doesn't change anything. That's a separate issue. Even if byLine was a field, using it would alter the underlying File.
Jan 30 2010
Wed, 27 Jan 2010 18:34:57 +0100, Pelle MÃ¥nsson wrote:I disagree, I find the function calls without the () to be really prettifying. But maybe that's just me. I don't think that it causes serious bugs, you would see that it's an integer the moment you try and use it. It also helps changing code from/to functions. I really like this feature, and would miss it should it go away.I just can't understand why implementing the optional ()s can be so hard. Scala does it and as far as I know, the solution doesn't have any problems. They also solved the property issues. In scala property methods have special names to distinguish them. object foo { def prop = 42; def prop_=(a: Int) = println(a) } defined module foo scala> foo.prop = 42 42 scala> object foo { def prop = 42; def prop_=(a: Int) = println(a) } defined module foo scala> foo.prop res12: Int = 42 scala> foo.prop() <console>:6: error: foo.prop of type Int does not take parameters foo.prop() ^ scala> foo.prop = 42 42 scala> foo.prop(42) <console>:6: error: foo.prop of type Int does not take parameters foo.prop(42) ^ scala> foo.prop_(42) <console>:6: error: value prop_ is not a member of object foo foo.prop_(42) ^ scala> foo.prop_=(42) 42 scala> foo.prop += 1 43
Jan 28 2010
Andrei Alexandrescu Wrote:Michiel Helvensteijn wrote:No no no. byLine returns a struct, it does not modify stdin. Operating on the struct modifies stdin, but that is outside the call to the property getter. Look at it this way (although this is not the only way to look at it), could byLine be a field inside stdin? It could. You could store a copy of what byLine returns inside stdin, and people could just access it.Andrei Alexandrescu wrote:byLine() is a function. It changes the state of stdin. Calling it consecutively will in general result in different return values. If there were two guys: stdin.currentLine (property) and stdin.nextLine(), it would be a different story.Damn. I was sure the answer will be different.foreach (line; stdin.byLine()) { ... } vs. foreach (line; stdin.byLine) { ... } How do I choose?byLine is a property. It is fetching a range on stdin. -SteveThere are some cases that are judgement calls and some that are obvious. byLine is obvious. The difference is that the *author* is making the judgement call, not the *user*. The difference is important, because when a user complains that your property is doing things a property shouldn't, and then you realize the "property" in question isn't even a property at all, your only solution (with the non-attributed system) is to tell the user not to use it that way. There is no way to get him to stop, or to get other users to stop. You have lost control over the semantic meaning of your function, even though you defined it and documented it. And yes, this did actually happen to me.A property should act very much like a field. The advantages of properties are that they can be derived (not have a one-to-one relation with a storage location) or can do some clever caching/memoizing/logging.I agree, but I'll also note that I got contradictory opinions from different supporters of property. So now it looks all the more like a judgment call, which is exactly what I was worried in the first place.This is your opinion when reading *your* code. It doesn't suck if you value being able to read code written by *others*. -SteveOmitting parentheses on an action just because you can is stupid. It actually makes the language less readable and less predictable. And all that for saving two keystrokes.I found my code to be more readable and just as predictable with the current rule. And it's not about two keystrokes, it's about persistent and ubiquitous syntactic noise. Gosh, property does suck. I was afraid that'd be true.
Jan 28 2010
On 01/29/2010 05:20 AM, Steven Schveighoffer wrote:Look at it this way (although this is not the only way to look at it), could byLine be a field inside stdin? It could. You could store a copy of what byLine returns inside stdin, and people could just access it.byLine modifies stdin. If you do this: auto a = stdin.byLine; You consume a line off stdin.There are some cases that are judgement calls and some that are obvious. byLine is obvious.Apparently not.The difference is that the *author* is making the judgement call, not the *user*. The difference is important, because when a user complains that your property is doing things a property shouldn't, and then you realize the "property" in question isn't even a property at all, your only solution (with the non-attributed system) is to tell the user not to use it that way. There is no way to get him to stop, or to get other users to stop. You have lost control over the semantic meaning of your function, even though you defined it and documented it. And yes, this did actually happen to me.Sounds like a naming issue to me. :)
Jan 29 2010
On Fri, 29 Jan 2010 06:16:15 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:On 01/29/2010 05:20 AM, Steven Schveighoffer wrote:That's a deficiency in the design of byLine. It's a range that "primes" itself with a line of text. The fact that you can enter the line above and just throw away the data seems error prone to me. When would you ever use that "feature"? In practice, it doesn't matter, because the only purpose to fetch the byLine struct is to iterate data from stdin. The design could be fixed with a boolean isPrimed that is unset on the first call to front. But like I said, it doesn't matter in the long run, since nobody ever fetches byLine without using it. I find that the shoehorning of an input range onto a stream is always going to have this problem, so there's not much we can do about it. It doesn't change the concept that byLine is a property. I find streams much better suited to opApply, but I've already had that unsuccessful battle, and I don't want to have it again.Look at it this way (although this is not the only way to look at it), could byLine be a field inside stdin? It could. You could store a copy of what byLine returns inside stdin, and people could just access it.byLine modifies stdin. If you do this: auto a = stdin.byLine; You consume a line off stdin.I don't see why you think it's not a property. It fetches a range from stdin, there is no other purpose. If you think byLine's purpose is to throw away a line of text, I think first that you are now attaching unintended semantic meaning to it (exactly what properties are meant to prevent) and second, I'd consider it to be a poorly named function. I guess someone should complain that it's not called popLine(), because as a function, that's what it does.There are some cases that are judgement calls and some that are obvious. byLine is obvious.Apparently not.You be the judge: http://www.dsource.org/projects/tango/ticket/1184 I find the resulting workaround very unsavory. -SteveThe difference is that the *author* is making the judgement call, not the *user*. The difference is important, because when a user complains that your property is doing things a property shouldn't, and then you realize the "property" in question isn't even a property at all, your only solution (with the non-attributed system) is to tell the user not to use it that way. There is no way to get him to stop, or to get other users to stop. You have lost control over the semantic meaning of your function, even though you defined it and documented it. And yes, this did actually happen to me.Sounds like a naming issue to me. :)
Jan 29 2010
On 01/29/2010 02:01 PM, Steven Schveighoffer wrote:That's a deficiency in the design of byLine. It's a range that "primes" itself with a line of text. The fact that you can enter the line above and just throw away the data seems error prone to me. When would you ever use that "feature"? In practice, it doesn't matter, because the only purpose to fetch the byLine struct is to iterate data from stdin. The design could be fixed with a boolean isPrimed that is unset on the first call to front. But like I said, it doesn't matter in the long run, since nobody ever fetches byLine without using it. I find that the shoehorning of an input range onto a stream is always going to have this problem, so there's not much we can do about it. It doesn't change the concept that byLine is a property. I find streams much better suited to opApply, but I've already had that unsuccessful battle, and I don't want to have it again.So byLine should be a property when implemented as a range, and a function when implemented as an opApply based loop? I feel that is a problem.You be the judge: http://www.dsource.org/projects/tango/ticket/1184 I find the resulting workaround very unsavory. -SteveThat's the assignment syntax, which I do agree is weird. Sorry if I was unclear. This is what I thought property was for. It has, however, nothing to do with the omitting of the ().
Jan 29 2010
On Fri, 29 Jan 2010 12:42:57 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:On 01/29/2010 02:01 PM, Steven Schveighoffer wrote:I meant byLine should return a struct that implements opApply. If it is a function then you have to pass the address to foreach, which is a little awkward.That's a deficiency in the design of byLine. It's a range that "primes" itself with a line of text. The fact that you can enter the line above and just throw away the data seems error prone to me. When would you ever use that "feature"? In practice, it doesn't matter, because the only purpose to fetch the byLine struct is to iterate data from stdin. The design could be fixed with a boolean isPrimed that is unset on the first call to front. But like I said, it doesn't matter in the long run, since nobody ever fetches byLine without using it. I find that the shoehorning of an input range onto a stream is always going to have this problem, so there's not much we can do about it. It doesn't change the concept that byLine is a property. I find streams much better suited to opApply, but I've already had that unsuccessful battle, and I don't want to have it again.So byLine should be a property when implemented as a range, and a function when implemented as an opApply based loop?No, but it is an example of someone misinterpreting the meaning of a function because the compiler accepted his syntax. Yes, the assignment rewrite is more troublesome than the getter, but being able to force someone to omit the parentheses has its advantages: user1: When I call range.empty(), it doesn't clear the range developer: Hm.. empty is not an action, its a property. Maybe I'll fix it by changing it to isEmpty to make it clear. user1: great idea! that's much clearer. .... user2: Why did you name it isEmpty, isn't the 'is' redundant since this looks perfectly normal? if(r.empty) developer: *sigh* This is the problem I ran into. Because so much meaning is attached to the () by humans, you must resort to naming conventions to make the intentions clear, then point out the reasons for not using a better name to future complainers. Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses. The no-parens property requirement has nothing to do with compiler interpretation or functionality and everything to do with human interpretation. It's all about what does the call *look* like it's doing as opposed to what it actually does. By enforcing the removal of parentheses, most normal users don't have to read the docs or look at anything else. It just works the way it's supposed to work, and looks like it does that. This doesn't make every single case clear, nor does it install automatic wisdom in all developers to be able to invent intuitive names. What it does is make it *possible* for you to invent intuitive names that retain their meaning and are succinct. I don't know about you, but using libraries with intuitive, consistent, and succinct terminology is really much more enjoyable than ones with inconsistent or overly verbose terminology. The other benefit is it makes calling delegate properties less ugly and more consistent with analogous fields. -SteveYou be the judge: http://www.dsource.org/projects/tango/ticket/1184 I find the resulting workaround very unsavory. -SteveThat's the assignment syntax, which I do agree is weird. Sorry if I was unclear. This is what I thought property was for. It has, however, nothing to do with the omitting of the ().
Jan 29 2010
On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.
Jan 29 2010
On Fri, 29 Jan 2010 13:43:50 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:You've cited three functions where the function names cannot be misinterpreted as properties. This is not the case for all function names. If you wish to have a way to specify a function can be called either way, then I think you also need a way to specify that a function can only be called with parentheses. I don't disagree that the above is unambiguous, but there are examples where it is ambiguous. f.read; does this mean read f, or is it an accidental noop fetching a property indicating f is read? Requiring parentheses also allows you to force meanings where they would otherwise be interpreted as properties: f.next(); Looks like it advances f, even though next isn't a verb. Without the parentheses, it looks like a noop access of a property. I'm not too concerned with requiring () on your examples because it's inconsequential to me -- having parentheses isn't *less* clear than not having them. I don't mind if you wish to allow these calls without parens, but there has to still be a way to force the parens. -SteveNote in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.
Jan 29 2010
On 01/29/2010 08:07 PM, Steven Schveighoffer wrote:On Fri, 29 Jan 2010 13:43:50 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:I disagree, it doesn't look like it advances. With the parens, it just looks like a java-style get-function. To me, at least.On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:You've cited three functions where the function names cannot be misinterpreted as properties. This is not the case for all function names. If you wish to have a way to specify a function can be called either way, then I think you also need a way to specify that a function can only be called with parentheses. I don't disagree that the above is unambiguous, but there are examples where it is ambiguous. f.read; does this mean read f, or is it an accidental noop fetching a property indicating f is read? Requiring parentheses also allows you to force meanings where they would otherwise be interpreted as properties: f.next(); Looks like it advances f, even though next isn't a verb. Without the parentheses, it looks like a noop access of a property.Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.I'm not too concerned with requiring () on your examples because it's inconsequential to me -- having parentheses isn't *less* clear than not having them. I don't mind if you wish to allow these calls without parens, but there has to still be a way to force the parens. -SteveI disagree. I understand that in some cases we would not want to permit calling with parenthesis, and that calling as assignment is sometimes less than ideal. I do not, however, see any reason to allow forcing of parenthesis for regular functions.
Jan 29 2010
On Fri, 29 Jan 2010 14:23:55 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:On 01/29/2010 08:07 PM, Steven Schveighoffer wrote:If this were Java, I'd agree with you :) But even on Java, it would have to be getNext().f.next(); Looks like it advances f, even though next isn't a verb. Without the parentheses, it looks like a noop access of a property.I disagree, it doesn't look like it advances. With the parens, it just looks like a java-style get-function. To me, at least.I guess D can't please everybody all the time. Oh well. -SteveI'm not too concerned with requiring () on your examples because it's inconsequential to me -- having parentheses isn't *less* clear than not having them. I don't mind if you wish to allow these calls without parens, but there has to still be a way to force the parens.I disagree. I understand that in some cases we would not want to permit calling with parenthesis, and that calling as assignment is sometimes less than ideal. I do not, however, see any reason to allow forcing of parenthesis for regular functions.
Jan 29 2010
Steven Schveighoffer wrote:On Fri, 29 Jan 2010 13:43:50 -0500, Pelle MÃ¥nsson <pelle.mansson gmail.com> wrote:"Rules are not meant to be followed robotically." Sorry I couldn't abstain :o).On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:You've cited three functions where the function names cannot be misinterpreted as properties. This is not the case for all function names. If you wish to have a way to specify a function can be called either way, then I think you also need a way to specify that a function can only be called with parentheses. I don't disagree that the above is unambiguous, but there are examples where it is ambiguous. f.read; does this mean read f, or is it an accidental noop fetching a property indicating f is read?Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.Requiring parentheses also allows you to force meanings where they would otherwise be interpreted as properties: f.next(); Looks like it advances f, even though next isn't a verb. Without the parentheses, it looks like a noop access of a property. I'm not too concerned with requiring () on your examples because it's inconsequential to me -- having parentheses isn't *less* clear than not having them. I don't mind if you wish to allow these calls without parens, but there has to still be a way to force the parens. -SteveOk how about this: if just calling the thing changes the parent, it can't be a property. Guess I could live with that. Andrei
Jan 29 2010
On Fri, Jan 29, 2010 at 12:02 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:ames.On Fri, 29 Jan 2010 13:43:50 -0500, Pelle M=E5nsson <pelle.mansson gmail.com> wrote:On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:You've cited three functions where the function names cannot be misinterpreted as properties. =A0This is not the case for all function n=Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln =3D 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.way,=A0If you wish to have a way to specify a function can be called either =rens,then I think you also need a way to specify that a function can only be called with parentheses. I don't disagree that the above is unambiguous, but there are examples where it is ambiguous. f.read; does this mean read f, or is it an accidental noop fetching a property indicating f is read?"Rules are not meant to be followed robotically." Sorry I couldn't abstain :o).Requiring parentheses also allows you to force meanings where they would otherwise be interpreted as properties: f.next(); Looks like it advances f, even though next isn't a verb. =A0Without the parentheses, it looks like a noop access of a property. I'm not too concerned with requiring () on your examples because it's inconsequential to me -- having parentheses isn't *less* clear than not having them. =A0I don't mind if you wish to allow these calls without pa=bebut there has to still be a way to force the parens. -SteveOk how about this: if just calling the thing changes the parent, it can't=a property. Guess I could live with that.Should be "if calling the thing changes the parent in an outwardly visible way". Doing refcounting or caching mutations under the hood should be ok. --bb
Jan 29 2010
On 2010-01-29 15:02:13 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Ok how about this: if just calling the thing changes the parent, it can't be a property. Guess I could live with that.Hopefully that rule will only apply to the getter. :-) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2010
"Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjv9sf$1n5o$1 digitalmars.com...On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:To me, at a glance, it looks like a series of no-ops. Like "x; y; z;". Only upon closer inspection of the names does it become apperent that functions are actually being called.Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.
Jan 29 2010
Nick Sabalausky wrote:"Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjv9sf$1n5o$1 digitalmars.com...A consequence of this discussion is that the built-in properties .reverse and .sort MUST be renamed. (Removal would be an acceptable form of renaming IMHO).On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:To me, at a glance, it looks like a series of no-ops. Like "x; y; z;". Only upon closer inspection of the names does it become apperent that functions are actually being called.Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.
Jan 31 2010
== Quote from Don (nospam nospam.com)'s articleNick Sabalausky wrote:Yea, can anyone even come up with a good Devil's Advocate argument in favor of leaving these in? The best one I can think of is that, since arrays in D are builtin, the basic functionality for them should also be builtin so they feel "first-class". This is a pretty weak argument. The builtins made sense early on, but now they are slow, inflexible and not substantially easier to use than the std.algorithm functions."Pelle Månsson" <pelle.mansson gmail.com> wrote in message news:hjv9sf$1n5o$1 digitalmars.com...A consequence of this discussion is that the built-in properties .reverse and .sort MUST be renamed. (Removal would be an acceptable form of renaming IMHO).On 01/29/2010 07:10 PM, Steven Schveighoffer wrote:To me, at a glance, it looks like a series of no-ops. Like "x; y; z;". Only upon closer inspection of the names does it become apperent that functions are actually being called.Note in the anecdote above, both users would have been satisfied if you could *only* call empty without parentheses.That's a good point. The writeln = 3; is also a good point. :) What I'm trying to defend is the ability to call non-property functions without the parens. I find this: array.stable_sort; file.detach; range.popFront; to look less noisy, clearer and just plain sexier than the respective versions with the parens.
Jan 31 2010
dsimcha:Yea, can anyone even come up with a good Devil's Advocate argument in favor of leaving these in? The best one I can think of is that, since arrays in D are builtin, the basic functionality for them should also be builtin so they feel "first-class". This is a pretty weak argument. The builtins made sense early on, but now they are slow, inflexible and not substantially easier to use than the std.algorithm functions.I don't know. The built-in sort is certified broken, very slow, and too much rigid. But I like the idea of a language that has built-in some very common operations, especially if it already has built-in data structures (like dynamic arrays and associative arrays. Associative arrays are a complex data structure). The good thing of the built in sort is that if you have to sort small groups of many different types of data, you don't need to import algorithms and your binary doesn't inflate because of all those different instances of the sort templated function. In the end I think that: - The sort method from the dynamic arrays can be removed; - The reverse method can be kept; - More useful methods can be added to the associative arrays, I have written about this in the past few times. Bye, bearophile
Jan 31 2010
On 29.01.2010 05:20, Steven Schveighoffer wrote:Andrei Alexandrescu Wrote:Before more time is wasted in this discussion, I would like to point out that byLine does actually have two arguments. I wrote a post about byLine yesterday, but noone seems to have noticed..Michiel Helvensteijn wrote: > Andrei Alexandrescu wrote: > >>>> foreach (line; stdin.byLine()) { ... } >>>> >>>> vs. >>>> >>>> foreach (line; stdin.byLine) { ... } >>>> >>>> How do I choose? >>> byLine is a property. It is fetching a range on stdin. >>> >>> -Steve >> Damn. I was sure the answer will be different. > > byLine() is a function. It changes the state of stdin. Calling it > consecutively will in general result in different return values. If there > were two guys: stdin.currentLine (property) and stdin.nextLine(), it would > be a different story.No no no. byLine returns a struct, it does not modify stdin. Operating on the struct modifies stdin, but that is outside the call to the property getter. Look at it this way (although this is not the only way to look at it), could byLine be a field inside stdin? It could. You could store a copy of what byLine returns inside stdin, and people could just access it.
Jan 31 2010