digitalmars.D - property - take it behind the woodshed and shoot it?
- Walter Bright (12/12) Jan 24 2013 This has turned into a monster. We've taken 2 or 3 wrong turns somewhere...
- Jacob Carlborg (7/19) Jan 24 2013 So:
- Walter Bright (3/12) Jan 24 2013 Yes.
- Andrei Alexandrescu (8/29) Jan 24 2013 That means there must be two overloads of f exactly:
- deadalnix (3/6) Jan 24 2013 I generic code, bugs I predict !
- Andrei Alexandrescu (3/10) Jan 24 2013 I agree it's something one must mind.
- Walter Bright (5/12) Jan 24 2013 I would also count:
- Peter Alexander (12/19) Jan 24 2013 How about generic code?
- Andrei Alexandrescu (4/24) Jan 24 2013 Agreed. This is a good litmus test. One option we had in mind was to
- Adam D. Ruppe (4/6) Jan 24 2013 It seems we've gone full circle. Tends to happen when you try to
- Adam D. Ruppe (35/35) Jan 24 2013 Thinking about it, this isn't quite a full circle. It does
- Andrei Alexandrescu (4/14) Jan 24 2013 Interesting, thanks.
- sclytrack (5/42) Jan 27 2013 If this means keeping the writeln = ""; then vote++. I've got no
- anonymous (7/28) Jan 27 2013 Also since you can't overload @property opDispatch and opDispatch
- Walter Bright (2/30) Jan 24 2013 Another option is f(args) always requires parens, even if args expands t...
- Walter Bright (2/6) Jan 24 2013 There could also be f(U), f(V), etc., just that the are all 0 or 1 arg.
- Jacob Carlborg (12/15) Jan 25 2013 That's somewhat problematic since it won't allow chaining assignments:
- deadalnix (4/19) Jan 25 2013 Assignation is right associative, so it is equivalent to :
- Jacob Carlborg (5/8) Jan 25 2013 That's what I'm saying, the setter needs to be able to return something
- mist (6/13) Jan 25 2013 Hm, shouldn't it be processed like that:
- Jacob Carlborg (4/9) Jan 25 2013 Yes, but why would a setter be called at step 3?
- mist (3/10) Jan 25 2013 Was thinking about i setter, did not pay attention it is actually
- anonymous (5/9) Jan 24 2013 You went half the way and now you're tired. Going back will be
- Namespace (2/13) Jan 24 2013 +1
- Andrei Alexandrescu (3/12) Jan 24 2013 This is a fix.
- Don (8/22) Jan 24 2013 I agree, the cure seems to be ten times worse than the disease.
- Walter Bright (2/5) Jan 24 2013 Jacob's should do.
- Minas Mina (12/12) Jan 24 2013 f = g; where it means f(g) is really ugly. I wouldn't like to see
- monarch_dodra (3/15) Jan 24 2013 @property also makes sense for global functions that need to
- Walter Bright (6/11) Jan 24 2013 Eeeyup. As for it being 'ugly', yes, it is a bit unsettling to us old ti...
- Manfred Nowak (13/14) Jan 24 2013 Yes!
- Nick Treleaven (6/15) Jan 24 2013 How about:
- Philippe Sigaud (7/11) Jan 24 2013 I made a stab at it in a template tutorial that can be found on github:
- Manfred Nowak (14/15) Jan 24 2013 Cough! `cfln' would eliminate the five letters `write'. For which
- Philippe Sigaud (7/21) Jan 25 2013 :)
- Manfred Nowak (8/11) Jan 25 2013 I am not interested in formatting at all. I wrote about the
- Philippe Sigaud (15/22) Jan 25 2013 And what's the solution, for you? Using strings as DSL is somewhat commo...
- Andrei Alexandrescu (3/19) Jan 26 2013 Looking forward to your talk? :o)
- Artur Skawina (21/39) Jan 26 2013 I think his point was that inventing a custom dsl for everything does
- Artur Skawina (5/7) Jan 26 2013 Found it. Unfortunately the old compiler here can't handle newer D
- Nick Treleaven (5/18) Jan 25 2013 Yes, I wish that was in Phobos ;-)
- Manfred Nowak (6/7) Jan 24 2013 Iff at all I prefer `write!someExpression= "%s\n";'
- Simen Kjaeraas (5/11) Jan 25 2013 From what I can see, Nick's solution allows compile time validity
- Manfred Nowak (6/8) Jan 25 2013 To me it is a syntactical change only. Where can I find the
- Manfred Nowak (4/5) Jan 24 2013 yippee!
- mist (13/13) Jan 24 2013 I am probably I minority here but I liked the most strict
- Artur Skawina (3/4) Jan 24 2013 Language design is not a popularity contest.
- mist (6/10) Jan 24 2013 Well most discussions seems to flow around simple preference
- Artur Skawina (18/25) Jan 24 2013 It's not merely "important"; it is essential.
- Andrei Alexandrescu (8/10) Jan 24 2013 You see, this is the kind of argument that I find very damaging to the
- Artur Skawina (24/29) Jan 24 2013 You're more than welcome to produce counterevidence, or ignore the argum...
- Andrei Alexandrescu (12/32) Jan 24 2013 Good quality discussion is always welcome. I have specifically opposed a...
- Timon Gehr (2/10) Jan 24 2013 There is no bug.
- Artur Skawina (8/18) Jan 24 2013 Bug? In Timon's code? Impossible. :)
- Andrei Alexandrescu (7/24) Jan 24 2013 Of course it is. The definition is simple enough, e.g. from Wikipedia:
- Artur Skawina (23/39) Jan 25 2013 Hmm, I can see how you could view this as an ad hominem, given that defi...
- Andrei Alexandrescu (8/27) Jan 25 2013 How can that be seen as anything else? What definition do you have?
- John T (6/9) Jan 25 2013 At this point, the only difference between you and Nick S. is the
- Artur Skawina (16/36) Jan 25 2013 No. Please don't try to reinterpret what I said, this is the second time...
- Nick Sabalausky (13/29) Jan 25 2013 "Ad hominem" *as a logical fallacy* is only applicable when the
- Timon Gehr (31/42) Jan 24 2013 Uh...
- deadalnix (9/18) Jan 24 2013 Let me rephrase that in a proper way.
- Timon Gehr (9/28) Jan 24 2013 The main issue is horrible garbage collector performance for many small
- kenji hara (12/16) Jan 24 2013 I'd like to add a rule which forgotten to mention about optional
- Johannes Pfau (7/20) Jan 24 2013 +1
- Andrei Alexandrescu (7/17) Jan 24 2013 It becomes way uglier with templates:
- mist (19/35) Jan 24 2013 I can hardly see any problems in your code sample. Syntax
- Andrei Alexandrescu (3/6) Jan 24 2013 This is the case with any property implementation.
- mist (10/18) Jan 24 2013 Not really. Good property usage is somewhat similar to unsafe
- Nick Sabalausky (4/14) Jan 24 2013 +1
- deadalnix (4/10) Jan 24 2013 I always create dumb lambda to do so as going fully functional is
- Timon Gehr (2/10) Jan 24 2013 And just as pointless.
- Bernard Helyer (18/32) Jan 24 2013 This is lazy design, plain and simple. You say it's turned into
- bearophile (7/12) Jan 24 2013 Sounds OK.
- Jacob Carlborg (4/5) Jan 24 2013 It would break tons of code.
- bearophile (11/12) Jan 24 2013 How much work does it take to change that makes and compilation
- Jacob Carlborg (5/14) Jan 24 2013 I agree with you but Walter is very afraid of breaking code.
- Walter Bright (3/4) Jan 24 2013 The history of what happens when D code breaks because of language chang...
-
mist
(12/16)
Jan 24 2013
Please. Go to http://wiki.dlang.org/Release_Process . Read - Andrei Alexandrescu (4/5) Jan 24 2013 There's just a lot of evidence that suggests the contrary. Clearly we
- mist (10/16) Jan 24 2013 Do you read and answer only to the first sentence? Can you
- Andrei Alexandrescu (5/21) Jan 24 2013 Clearly the design is imperfect.
- mist (9/10) Jan 25 2013 Sorry Andrei, with all my due respect, you have a brilliant
- Jonathan M Davis (15/36) Jan 24 2013 The problem is that we have competing goals that we have to deal with
- Adam Wilson (22/67) Jan 24 2013 I don't think we can fix @property (or remove it) without breaking code....
- Adam D. Ruppe (4/5) Jan 24 2013 This has absolutely nothing to do with properties because
- Adam Wilson (10/15) Jan 24 2013 From the compilers standpoint they are functions. It must be so. That's...
- Adam D. Ruppe (25/27) Jan 24 2013 No, they are @property functions. That's important because it
- deadalnix (29/34) Jan 24 2013 If you or Walter think that D is somehow stable or backward
- Walter Bright (3/12) Jan 24 2013 Having a release process does not remove the pain of breaking changes th...
- deadalnix (3/7) Jan 24 2013 That is why semantic needs to be clean. Semy hacky stuff ends up
- Don (14/18) Jan 25 2013 I don't believe that is true. Remember when 'bit' was removed
- mist (5/6) Jan 25 2013 ++
- Andrei Alexandrescu (4/22) Jan 25 2013 TDPL did exactly that. For example it doesn't mention foreach_reverse or...
- deadalnix (3/6) Jan 25 2013 Wise move !
- Dmitry Olshansky (4/22) Jan 25 2013 +1
- Andrei Alexandrescu (4/6) Jan 24 2013 No. @property is bad design, pure and simple. It's great that we're
- mist (5/9) Jan 24 2013 And yet it must have been done at some point. With some
- bearophile (5/7) Jan 24 2013 Don't forget that our discussions in this thread are mostly
- Jacob Carlborg (5/8) Jan 24 2013 Yes, it was a horrible design error but it didn't break any code
- mist (9/17) Jan 24 2013 Design error was to not force "-property" since the very
- eles (3/10) Jan 24 2013 I would say: kill -property, not @property.
- Manu (7/37) Jan 24 2013 Absolutely agree.
- Andrei Alexandrescu (7/35) Jan 24 2013 No. The complications come from the fact that (a) nobody could agree
- David Nadlinger (5/11) Jan 24 2013 The simple(r) explanation is: The current *implementation* is
- Andrei Alexandrescu (3/10) Jan 24 2013 Simpler doesn't make it true.
- Jonathan M Davis (4/16) Jan 24 2013 Exactly. Most of the problems with @property stem from the fact that it'...
- Andrei Alexandrescu (3/18) Jan 24 2013 That is because it's not well defined.
- Johannes Pfau (13/21) Jan 24 2013 There are only 2 kinds of programmers: Those who read the C# guidelines
- Nick Sabalausky (38/80) Jan 24 2013 No, you merely came up with *some* specific cherry-picked examples that
- Andrei Alexandrescu (3/8) Jan 24 2013 I simply mentioned three reasons that came to mind.
- Adam Wilson (17/25) Jan 24 2013 While I don't approve of Mr. Sabalausky's tone or attitude, the crux of ...
- Jonathan M Davis (8/33) Jan 24 2013 Exactly. That's what _should_ have happened. We wouldn't have all of the...
- Adam Wilson (15/54) Jan 24 2013 All I can say is that in this case even with UFCS C# enforces parens
- Timon Gehr (5/15) Jan 24 2013 It is not a shortcut, it is a formatting option, and using it does not
- Adam Wilson (40/57) Jan 24 2013 *sigh* ideally yes, it's just a formating option. The problem is that
- Timon Gehr (20/32) Jan 24 2013 You mean, a parameterless delegate. How many times does this occur that
- Andrei Alexandrescu (3/39) Jan 24 2013 I feel we're getting somewhere!
- kenji hara (8/70) Jan 24 2013 1. Optional parentheses for normal functions should work shallowly IMO.
- Adam Wilson (9/104) Jan 24 2013 I can completely agree with this change. It is perfectly workable to fix...
- kenji hara (15/32) Jan 24 2013 I have thought an additional idea.
- Adam Wilson (9/44) Jan 24 2013 Very clever Mr. Hara, I like it a lot! But good luck convincing
- Andrei Alexandrescu (7/21) Jan 24 2013 Brings completeness. But at this point I'm inclined to simplify,
- deadalnix (6/20) Jan 24 2013 @function seems like an extra complication. Ambiguity between
- kenji hara (12/17) Jan 24 2013 That's a good point. We need to solve another ambiguity about top-level
- mist (7/16) Jan 25 2013 "1.foo" must be compile error here. Makes as much sense as
- TommiT (13/32) Jan 25 2013 I don't see 1.foo the way you see it. I see it like this:
- TommiT (3/4) Jan 25 2013 But I don't see why that should matter.
- mist (5/17) Jan 25 2013 It is a tempting attempt to save two symbols of typing that
- TommiT (17/21) Jan 25 2013 My understanding of the point of UFCS has been that it enables
- mist (31/31) Jan 25 2013 Meaning of @property for free functions is well-defined. Most
- Jacob Carlborg (5/7) Jan 25 2013 C# doesn't have UFCS but it does have a syntax for adding new methods
- mist (7/14) Jan 25 2013 Great, could you give a sample? Does it work on compile time or
- Jacob Carlborg (20/25) Jan 25 2013 The secret is to add "this" in front of the argument type you want to
- mist (3/21) Jan 25 2013 Good. Main questions remain though: is property syntax allowed on
- Jacob Carlborg (5/7) Jan 25 2013 I'm not particular familiar with this, perhaps someone else can answer
- deadalnix (3/34) Jan 25 2013 See what is proposed here :
- mist (3/5) Jan 25 2013 Looks somewhat solid to me, with some disagreement on UFCS side
- Nick Sabalausky (4/25) Jan 25 2013 I think you might have misunderstood it. What he's trying to do is use
- mist (7/10) Jan 25 2013 I got it. What I am questioning is that allowing this in some way
- Jonathan M Davis (12/34) Jan 24 2013 Well, better that then get rid of @property. The other big question is w...
- deadalnix (3/12) Jan 24 2013 Can you explain the problem you see with opDispatch ?
- Jonathan M Davis (7/21) Jan 24 2013 If you make opDispatch @property, then you can't use it with normal func...
- deadalnix (21/30) Jan 24 2013 OK, so opDispatch must definitively be transformed ! I have to
- eles (3/40) Jan 25 2013 I dunno, but for me the line above is a function pointer that is
- kenji hara (8/20) Jan 24 2013 I think calling a function which does not annotated with @attribute with...
- deadalnix (3/31) Jan 24 2013 English grammar don't have any functional style enable. It is not
- Walter Bright (5/11) Jan 25 2013 There is a way to do #2 without breaking existing code.
- Jonathan M Davis (13/27) Jan 25 2013 Considering that it's always been the plan that @property would be enfor...
- deadalnix (2/18) Jan 25 2013 Yes, or maybe we should adopt a sane release process . . .
- Jonathan M Davis (9/36) Jan 25 2013 In fact, I'd argue that making @property enforce that a function be call...
- kenji hara (14/29) Jan 25 2013 Instead, we can simply change the semantic behavior, when -property swit...
- eles (8/12) Jan 25 2013 I think the way picked to do the change is, now, of secondary
- Jonathan M Davis (9/11) Jan 25 2013 I dispute that we can't just use @property since it was its design from ...
- Jonathan M Davis (9/16) Jan 24 2013 I'd say that we should do both. It's ridiculous to accept parens on prop...
- kenji hara (28/50) Jan 24 2013 Two months ago, I've tried to implement the rule and posted an experimen...
- Timon Gehr (4/27) Jan 24 2013 This is a serious issue.
- Adam D. Ruppe (12/14) Jan 24 2013 http://msdn.microsoft.com/en-us/library/w86s7x04(v=VS.80).aspx
- Adam Wilson (12/24) Jan 24 2013 The problem is that optional parens introduce ambiguity in relation to
- Adam D. Ruppe (17/20) Jan 24 2013 No, it doesn't.
- Adam Wilson (13/31) Jan 24 2013 Right, this conversation is about removing @property, which invalidates ...
- Adam D. Ruppe (4/8) Jan 24 2013 I did.... on my modified dmd where @property has a less stupid
- Adam Wilson (10/18) Jan 24 2013 Hehe, so am I! :-)
- Adam D. Ruppe (18/20) Jan 24 2013 No, this isn't a problem; function call syntax has nothing
- Jonathan M Davis (15/40) Jan 24 2013 D's insistance on optional parens _does_ cause problems with functions t...
- Nick Sabalausky (6/11) Jan 24 2013 I should clarify that this is my view as well. I may be vocally opposed
- kenji hara (5/16) Jan 24 2013 We can delay the decision about "optional parentheses for normal functio...
- kenji hara (12/23) Jan 24 2013 I think that the "optional parentheses" feature for normal functions sho...
- Adam D. Ruppe (2/4) Jan 24 2013 I agree. This is the way it makes sense (and the way it is now).
- Andrei Alexandrescu (3/7) Jan 24 2013 So would Kenji's proposal float your boat?
- Adam D. Ruppe (31/32) Jan 24 2013 Yeah, as described in more detail in this post:
- Andrei Alexandrescu (5/16) Jan 24 2013 Interesting, so that would mean if anyone ever wants to get the delegate...
- Jonathan M Davis (6/27) Jan 24 2013 I believe that that's what we have now. The problem is when you want a
- Andrei Alexandrescu (3/7) Jan 24 2013 Well how about we just renounce those for the sake of simplification.
- Jonathan M Davis (7/15) Jan 24 2013 Without explicit properties you can't switch back and forth between some...
- Jonathan M Davis (18/36) Jan 24 2013 And actually, something far more important than any of those reasons is ...
- kenji hara (5/32) Jan 24 2013 getter usage.
- deadalnix (6/16) Jan 24 2013 I don't understand. We want to drop feature that work in other
- Jacob Carlborg (4/10) Jan 25 2013 Yes, that's the way it's always been since the D1 days.
- Andrei Alexandrescu (5/26) Jan 24 2013 Simplicity is clearly good, but there's something to be said about those...
- Adam Wilson (14/44) Jan 24 2013 Then @property needs to be fixed such that optional parens don't effect ...
- Andrei Alexandrescu (10/21) Jan 24 2013 I'm not all that convinced, and it's easy to get wedged into a black vs
- Adam D. Ruppe (29/32) Jan 24 2013 An enum or a literal can't be passed by reference or otherwise
- Jonathan M Davis (7/18) Jan 24 2013 [snip]
- Adam D. Ruppe (3/6) Jan 24 2013 agreed
- Dmitry Olshansky (5/9) Jan 25 2013 IMHO this is a critical part of what a property should do -
- Jonathan M Davis (5/13) Jan 25 2013 And for that, we need to keep @property. It's impossible without explici...
- Adam Wilson (17/39) Jan 24 2013 ... wat? I fail to see what byref has to do with this. It shouldn't matt...
- Rob T (23/29) Jan 24 2013 On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu
- kenji hara (17/41) Jan 24 2013 I can imagine a situation that we might not want to treat property
- deadalnix (3/23) Jan 24 2013 Indeed ! @property should be different as far as reflection is
- Jacob Carlborg (5/15) Jan 25 2013 A serialization library would only recognize "value_" since it's an
- deadalnix (3/22) Jan 25 2013 getFields/getProperties/getMethods and you are done. It don't
- luka8088 (30/52) Jan 25 2013 Maybe this will clarify what is meant by "properties are data":
- Robert Schadek (6/48) Jan 24 2013 At while you're at it, just get ride of:
- Adam Wilson (13/67) Jan 24 2013 Well, from a syntax standpoint it's legitimate, and D's dynamic arrays a...
- Robert burner Schadek (4/70) Jan 25 2013 Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it
- mist (5/9) Jan 25 2013 Ye, it was one of the first "Erm wtf?" moments when I started to
- monarch_dodra (6/15) Jan 25 2013 I can view *reading* size as a property, but I don't think the
- mist (1/1) Jan 25 2013 Why? Other than "breaking code".
- Jonathan M Davis (15/33) Jan 25 2013 So? Of course, setters can throw exceptions. Why wouldn't they be able t...
- Nick Sabalausky (7/21) Jan 24 2013 And I simply pointed out how they are incorrect.
- Adam D. Ruppe (6/9) Jan 24 2013 I literally screamed at my computer screen a couple times in this
- Nick Sabalausky (7/18) Jan 24 2013 Getting screamed at and just taking it, without ever giving me crap back
- Nick Sabalausky (8/17) Jan 25 2013 What really got me upset about it was that here we have one of my
- Adam D. Ruppe (2/7) Jan 25 2013 Amen.
- Rob T (9/20) Jan 25 2013 If I correctly understand Walters proposal and Andrei's view
- Andrei Alexandrescu (8/21) Jan 25 2013 That's right with the amendment that we're looking for a solution, not
- Rob T (12/47) Jan 25 2013 OK, understood. I started a discussion in wiki showing how
- Jacob Carlborg (10/16) Jan 26 2013 It's always possible to avoid keywords in favor of syntax. Example:
- Nicolas Sicard (4/13) Jan 26 2013 How would you declare a template property? The getter would be
- Jacob Carlborg (4/6) Jan 26 2013 Right... didn't think of that.
- Andrei Alexandrescu (4/19) Jan 26 2013 This is interesting. I wonder how to make it work for UFCS functions
- deadalnix (4/37) Jan 26 2013 I have to say it will get my vote if a way if found to make this
- Jacob Carlborg (7/9) Jan 26 2013 There's two problems with the getter syntax.
- Regan Heath (8/34) Jan 28 2013 Do the c# thing and use 'this'? i.e.
- Adam Wilson (10/46) Jan 28 2013 Yes, C# uses a 'this' argument as it's first parameters to make it an
- Maxim Fomin (25/34) Jan 26 2013 This looks nice, but I favor for C# properties.
- Adam Wilson (20/56) Jan 26 2013 C# does not have a property keyword precisely because get/set are enough...
- Artur Skawina (22/56) Jan 26 2013 Hmm, the current state of them being defined by two separate functions r...
- Rob T (22/45) Jan 26 2013 In a more pefect world, we'd redefine what a variable and
- Ziad Hatahet (19/25) Jan 26 2013 That is what I have been noticing as well, unfortunately. As a long tim...
- Rob T (32/32) Jan 26 2013 We can almost implement properties as a regular struct
- H. S. Teoh (26/27) Jan 26 2013 [...]
- Rob T (12/37) Jan 26 2013 Ah cool! You don't really need @property however if we adopt the
- Artur Skawina (29/72) Jan 27 2013 auto w = Widget();
- Adam D. Ruppe (3/3) Jan 26 2013 It would be cool if we could declare variables with anonymous
- Zach the Mystic (5/8) Jan 26 2013 This would be much easier to understand:
- Zach the Mystic (3/12) Jan 26 2013 Actually, I don't even think you need alias:
- H. S. Teoh (37/40) Jan 26 2013 I was thinking we could just use a template to alleviate much of the
- Jacob Carlborg (4/24) Jan 27 2013 That might conflict with contracts, which also uses "in" and "out".
- Artur Skawina (13/40) Jan 27 2013 It overloads the keywords, but afaict should be unambiguous and is not
- Jacob Carlborg (5/11) Jan 27 2013 I'm not talking about confusing. I'm thinking if it's ambiguous or not
- Timon Gehr (8/17) Jan 27 2013 class A{
- Michael (20/28) Jan 27 2013 I think that "property as contract for accessing to variable" is
- Walter Bright (4/19) Jan 26 2013 It is rather similar to a variable declaration with initializer:
- Jacob Carlborg (5/9) Jan 27 2013 Yeah, you're right.
- Jacob Carlborg (5/14) Jan 25 2013 There are many languages that allow optional parentheses when calling a
- deadalnix (3/24) Jan 25 2013 From what I see on CofeeScript website, it has a VERY different
- Jacob Carlborg (5/7) Jan 25 2013 How do you mean? Well it has the same semantics as JavaScript since it's...
- Jonathan M Davis (10/63) Jan 24 2013 I've never understood what's so hard about knowing what should and shoul...
- ponce (3/4) Jan 24 2013 Looks fine for me. D2 code is better but sometimes so much
- David Nadlinger (39/53) Jan 24 2013 Under the proposed rules, which of the lines in the output of the
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (24/40) Jan 24 2013 I think Adam D. Ruppe has proposed this in the past and, although I don'...
- Jacob Carlborg (4/7) Jan 24 2013 +1
- deadalnix (6/38) Jan 24 2013 This greatly impairs functional style. Just as you demonstrated
- Iain Buclaw (6/18) Jan 24 2013 As much as I want to agree, I also feel this comes as too little, too la...
- Andrei Alexandrescu (3/20) Jan 24 2013 Too little is a good thing actually!
- d coder (2/4) Jan 24 2013 +1
- deadalnix (67/81) Jan 24 2013 I'm so unhappy to read this :(((((((
- Jacob Carlborg (7/31) Jan 24 2013 What about @property(getter) and @property(setter) instead? Otherwise we...
- deadalnix (8/45) Jan 24 2013 I don't really care about the syntax. If any new attribute has to
- Jacob Carlborg (5/8) Jan 24 2013 Then what do you mean by:
- deadalnix (7/15) Jan 24 2013 a.foo is the same as &a.foo . The reason is that &a.foo is used
- Andrei Alexandrescu (5/6) Jan 24 2013 Nothing like that at least from me but I can plainly say this proposal
- Chad J (8/14) Jan 25 2013 Wait, so Walter would be willing to ice @property, but deprecating it in...
- Walter Bright (2/9) Jan 24 2013 Dang, I hadn't thought of the typeof(funName) issue.
- Walter Bright (3/12) Jan 24 2013 On further thought, if funName is a property, then typeof(funName) shoul...
- mist (23/67) Jan 25 2013 Agree with differentiation but why no address? For me funName
- Adam D. Ruppe (21/21) Jan 24 2013 No, god no. This would break code AGAIN and still not fix the
- David Nadlinger (3/25) Jan 24 2013 I wholeheartedly agree.
- deadalnix (16/20) Jan 24 2013 I'll be rude, but that is needed.
- Jonathan M Davis (14/49) Jan 24 2013 Yes. I think that it's fairly clear that we need to do something like th...
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (2/24) Jan 24 2013 I see it exactly the same way.
- mist (50/50) Jan 24 2013 One thing I am interested to hear from ones who think allowing
- Alvaro (21/43) Jan 29 2013 I agree with Adam's view and I really think @property is a good
- Dmitry Olshansky (4/9) Jan 29 2013 A typo pretty much ruined otherwise good point :)
- Iain Buclaw (7/12) Jan 24 2013 Not going to happen. Effectively what is being proposed here is that we
- Andrej Mitrovic (18/24) Jan 24 2013 This is going to be a problem in API refactoring. if "f" used to be a
- Chad J (19/31) Jan 24 2013 I somehow feel like someone read my article from a couple years ago
- Robert Jacques (3/15) Jan 24 2013 vote++
- Adam Wilson (54/66) Jan 24 2013 I don't see what is so bloody difficult about this. C# has very good ver...
- mist (5/8) Jan 24 2013 This, this and this again. Reading this thread I sometimes get
- eles (9/10) Jan 24 2013 I think the widest spread use case of a property is:
- mist (5/17) Jan 24 2013 It is a wrong use case for a property. Necessity to change data
- Jonathan M Davis (15/37) Jan 24 2013 Being able to swap out a public variable with a function without having ...
- Adam Wilson (12/56) Jan 24 2013 ++ to Mr. Davis!
- mist (7/12) Jan 24 2013 Yes, but not just any function. Side-effect free function that
- Adam Wilson (12/21) Jan 24 2013 Actually I said that in C# is possible to write properties with
- mist (1/1) Jan 24 2013 %s/Adam/eles/g
- eles (7/7) Jan 24 2013 "more extensive processing" does not necessarily involve side
- Jonathan M Davis (25/42) Jan 24 2013 Another issue to consider is enhancements such as
- Chad J (4/46) Jan 24 2013 I think what you want is semantic property rewriting.
- Andrej Mitrovic (7/8) Jan 24 2013 It is super-ironic that you want to simply pull-out and destroy a
- Nathan M. Swan (9/23) Jan 24 2013 What about code that's always ignored @property?
- Sean Kelly (7/34) Jan 24 2013 somewhere.
- Jonathan M Davis (6/41) Jan 24 2013 I'd argue for simply making it so that the parens are required when a fu...
- Robert (36/36) Jan 24 2013 Apart from +=, ++, what breaks compatibility of fields and properties,
- Adam D. Ruppe (10/16) Jan 24 2013 If I get things my way, no. I'd rewrite that, internally, into
- Robert (3/6) Jan 24 2013 Yeah, I thought of that and the compiler can optimize it away if not
- Adam Wilson (24/60) Jan 24 2013 @Robert, C#'s auto-properties actually do something very close to that. ...
- Jacob Carlborg (7/9) Jan 25 2013 @property(get, set) int a;
- Adam Wilson (8/15) Jan 25 2013 This, for the love of all that is good in the world, a million times thi...
- Jacob Carlborg (4/10) Jan 25 2013 I think this syntax feels quite obvious.
- Jacob Carlborg (9/43) Jan 25 2013 I really like this. Although this is not really what the rest of the
- Robert (11/25) Jan 24 2013 -> field property, and get/set property are actually the same thing. ->
- Adam Wilson (9/34) Jan 24 2013 The syntax provides no way to define read-only or write-only properties....
- Robert (10/13) Jan 24 2013 There is, just don't do:
- Jacob Carlborg (7/9) Jan 25 2013 @property(get, set) int a;
- Adam Wilson (45/57) Jan 24 2013 I want to point out another usage of properties that invades my work eve...
- Adam Wilson (16/28) Jan 24 2013 I just worked through this with Alexander Bothe (of Mono-D fame). Here i...
- Andrei Alexandrescu (3/30) Jan 24 2013 This looks essentially the same as Walter's proposal.
- Timon Gehr (4/40) Jan 24 2013 Not at all. Walter's proposal just chooses the other option when stuff
- Adam Wilson (10/52) Jan 24 2013 Basically this. I was writing a longer post that essentially said this.
- Andrei Alexandrescu (4/6) Jan 24 2013 Definitely. But it shouldn't be forgotten that syntactic warts are also
- Adam Wilson (11/17) Jan 24 2013 I would argue that given how common they already are, cost of the wart i...
- Andrei Alexandrescu (5/18) Jan 24 2013 Again, the question needs asking: is it a given that we need to allow
- Jonathan M Davis (9/12) Jan 24 2013 I hate optional parentheses with a passion, but I think that it's quite ...
- eles (7/13) Jan 24 2013 I hate the optional parentheses (I really see no point for this
- eles (4/8) Jan 24 2013 Seriously, who wants to try criticizing this?:
- eles (7/12) Jan 24 2013 "Properties have many uses: they can validate data before
- Jonathan M Davis (25/40) Jan 24 2013 The issue is that lots of people like optional parentheses. I expect tha...
- eles (15/22) Jan 25 2013 I think the root reason of this fight over what properties are
- Jonathan M Davis (10/39) Jan 25 2013 I think that C#'s syntax (or something close to it) probably would have ...
- SomeDude (3/5) Jan 27 2013 Same here.
- sclytrack (4/11) Jan 27 2013 In Delphi they are also optional and nobody uses them. However,
- deadalnix (2/13) Jan 27 2013 Delphi has no real functional capabilities.
- Timon Gehr (2/16) Jan 27 2013 What about scala?
- deadalnix (4/23) Jan 27 2013 I'm not a scala specialist (however, one of my coworker is, so
- Michael (20/20) Jan 27 2013 int CoolThing { in; out; } - auto property without implementation;
- Jacob Carlborg (5/24) Jan 27 2013 Won't this conflict with contracts, which also uses the "in" and "out"
- Michael (2/7) Jan 27 2013
- TommiT (16/23) Jan 27 2013 If that's the level of abstraction on which you want to discuss
- Dicebot (9/20) Jan 27 2013 If we require clever IDE to distinguish visually something as
- deadalnix (6/27) Jan 27 2013 You're being an extremist here. From a vim user and automagic
- Dicebot (15/20) Jan 27 2013 Probably, but that is a result of general mainstream moving to
- Andrei Alexandrescu (20/47) Jan 27 2013 Language adoption is a complex phenomenon with many variables, and it's
- deadalnix (12/17) Jan 27 2013 That is kind of my point : such language is made for tooling.
- Jeff Nowakowski (21/39) Jan 27 2013 First off, where do you get this billion dollar marketing figure from?
- TommiT (10/17) Jan 27 2013 Notepad opens text files. There is nothing that says that the
- Dicebot (5/14) Jan 27 2013 Text is still most efficient form of providing information.
- TommiT (23/26) Jan 27 2013 Okay, here's what I invented in 5 minutes that would be better
- Dicebot (4/31) Jan 27 2013 And how it is any better? Also D sources are unicode, so last two
- TommiT (19/22) Jan 27 2013 I don't know if what I invented is any better, but my attempt was
- H. S. Teoh (18/22) Jan 27 2013 [...]
- Dicebot (17/40) Jan 27 2013 More noise -> not easier to read. It may has a merit when
- TommiT (6/10) Jan 27 2013 I was referring to Avid video editing software, which has been
- H. S. Teoh (43/45) Jan 27 2013 Because it's not *necessary*. Having a universal representation has many
- Artur Skawina (8/9) Jan 27 2013 Except we're not talking about such hypothetical language, but one where...
- TommiT (10/12) Jan 27 2013 I think we have been throwing the term ambiguous around too
- Dicebot (8/20) Jan 27 2013 "easy to read" == "I can find part of code that interests me
- Timon Gehr (4/8) Jan 27 2013 In order to do that, it is necessary aware of the precise definitions,
- Timon Gehr (2/11) Jan 27 2013
- Dicebot (11/15) Jan 28 2013 Sure, it is for compiler. And it for me if I check the definition
- Adam D. Ruppe (5/7) Jan 28 2013 However, as long as we have properties *at all* you'd have to
- Dicebot (10/17) Jan 28 2013 No, I am repeating this again and again - when I see a property I
- TommiT (8/11) Jan 28 2013 Do you consider a dynamic arrays' length property to be a good,
- Dicebot (3/7) Jan 28 2013 Then you need something other than properties.
- Andrei Alexandrescu (4/11) Jan 28 2013 Wait, so you're against any writable properties? Maybe there's a
- Dicebot (8/11) Jan 28 2013 Ah, yes, there is a confusion between "side-effect" from the pure
- Jacob Carlborg (4/10) Jan 28 2013 What about getters and setters and gets and sets a value from a cache?
- Dicebot (14/17) Jan 28 2013 Would not have made them properties either. It is somewhat
- TommiT (12/15) Jan 28 2013 I think you're putting too much faith on the power of convention
- Dicebot (4/20) Jan 28 2013 That is no different from volatile variables. My notion is at
- TommiT (14/26) Jan 28 2013 If you think my example of {start_time, end_time, duration}
- Dicebot (8/15) Jan 28 2013 T changes its inner encapsulated states. Period. It is no
- H. S. Teoh (11/29) Jan 28 2013 In the dinosaur age of Motorola 6502 processors, writing certain values
- David Nadlinger (7/11) Jan 28 2013 ... *and* possibly relocated in memory, so that it no longer
- TommiT (10/17) Jan 28 2013 The question "what is or should be a property?" is a question of
- Andrei Alexandrescu (3/18) Jan 28 2013 I guess you hate if people want their bigints to assign with a = b.
- Max Samukha (6/36) Jan 28 2013 widget.height = 100 should be condemned, too - it changes the
- Michael (8/14) Jan 28 2013 Yes, but also it's should be a lightweight action (main idea).
- Max Samukha (3/17) Jan 29 2013 I think we need something more measurable than lightweight-ness
- Dicebot (7/9) Jan 28 2013 Have never used bigints. You mean that copy construction upon
- Andrei Alexandrescu (4/12) Jan 28 2013 Well I think this is a given now. So again - time to adjust preferences ...
- eles (17/26) Jan 28 2013 My feeling is that the array.length getter/setter problem is
- Dicebot (4/5) Jan 29 2013 Ye, I know, I speak too much :( Sure, switching to low profile
- eles (2/7) Jan 29 2013 Reason and reasonable trade-off should prevail.
- Andrei Alexandrescu (3/6) Jan 29 2013 That's not the right conclusion.
- deadalnix (3/7) Jan 27 2013 That is not good because in functional style, you manipulate
- deadalnix (5/28) Jan 24 2013 It is NOT and workaround have been proposed to solve the UFCS ()
- eles (5/9) Jan 25 2013 You overlook that "get/set" in C# are none other than "@property"
- Andrei Alexandrescu (3/11) Jan 25 2013 Agreed.
- Jacob Carlborg (5/14) Jan 25 2013 This code contains explicit properties. Walter's proposal was to remove
- Jesse Phillips (14/17) Jan 24 2013 As mentioned, this seems dangerous. I'd suggest requiring when
- Adam Wilson (20/34) Jan 24 2013 The problem is that the moment we start talking about @property the
- Adam D. Ruppe (7/10) Jan 24 2013 Well, not right now - I made progress on it a while ago and hit a
- Adam Wilson (9/18) Jan 24 2013 I know how that is. No worries. My misunderstanding.
- Timon Gehr (5/11) Jan 24 2013 That might explain your bias. I had to work with C# for a project
- Jesse Phillips (14/24) Jan 25 2013 Well, I'd hope @property could give the compiler enough
- Rob T (33/35) Jan 25 2013 I think that observation pins the whole debate down, and it's an
- Adam D. Ruppe (6/9) Jan 25 2013 The reason @property exists in the first place is to fix the edge
- Rob T (17/27) Jan 25 2013 So historically, the fist implementation of the property concept
- Adam D. Ruppe (14/19) Jan 25 2013 That was actually before my time. The optional parens feature has
- Jacob Carlborg (6/8) Jan 26 2013 It seems just to be how things are done in the D community. Another
- deadalnix (3/10) Jan 26 2013 That is probably the #1 problem with D.
- Adam D. Ruppe (5/7) Jan 26 2013 That design is almost identical to a discussion we had a few
- Jacob Carlborg (5/8) Jan 26 2013 Not the syntax. Walter added a two syntaxes one deprecated using
- Andrei Alexandrescu (72/105) Jan 25 2013 I agree with all of the above. There has been a fair amount of
- mist (2/2) Jan 25 2013 Finally, stating some opinions clearly.
- Johannes Pfau (21/61) Jan 25 2013 Do that on this wiki page:
- Adam D. Ruppe (18/20) Jan 25 2013 These are examples of why I'm firmly in the pro-optional
- mist (12/12) Jan 25 2013 2 cents regarding your position on "@property" usage in phobos:
- Rob T (7/13) Jan 25 2013 This already works
- Jonathan M Davis (3/18) Jan 25 2013 They both already work and have do so for ages.
- mist (4/6) Jan 25 2013 Erm? Yes, and thus it was an answer to "you need to mess every
- Jonathan M Davis (4/13) Jan 25 2013 I know. I was responding to Rob's post which implied that the syntax you...
- Rob T (5/19) Jan 25 2013 I misread the post by mist, I incorrectly thought that it was a
- Jonathan M Davis (3/5) Jan 25 2013 : works works with any function attribute, as does {}.
- Jacob Carlborg (4/5) Jan 26 2013 And even for user defined attributes :)
- Jonathan M Davis (42/66) Jan 25 2013 That's simply a question of being able to make function calls without pa...
- Walter Bright (7/9) Jan 25 2013 I would have agreed with you on that for years, simply taking its veraci...
- Manfred Nowak (4/6) Jan 25 2013 Depending on the education under the hood is always a turing
- Mehrdad (8/20) Jan 25 2013 Walter, that's not how TLS variables are generally implemented in
- Walter Bright (4/7) Jan 25 2013 This is not necessarily true at all. It isn't for OSX, for example, and ...
- Mehrdad (18/29) Jan 25 2013 I wasn't being pedantic. That's why I said generally, not always.
- Walter Bright (2/5) Jan 26 2013 I.e. the difference is purely a contrivance, which was my point.
- deadalnix (3/10) Jan 26 2013 Yes, that the whole point of abstraction. It happen that
- Jacob Carlborg (9/12) Jan 26 2013 They can be implemented as a function call on (at least) Linux as well.
- Johannes Pfau (9/22) Jan 26 2013 Although variable access might be implemented as a non-trivial function
- deadalnix (38/86) Jan 25 2013 I don't understand why this is a special case in the first place.
- Dmitry Olshansky (7/60) Jan 26 2013 Automated tooling is admitting a defeat if we talk about expressive
- deadalnix (9/14) Jan 26 2013 Using tooling is admitting defeat ? That is very misplaced pride
- Dmitry Olshansky (10/24) Jan 26 2013 There is no pride. Requiring a separate tool to generate code even in
- Chad J (6/20) Jan 24 2013 This has nothing to do with @property. It has to do with defining what
- Jonathan M Davis (9/33) Jan 24 2013 Honestly, I don't think that English grammar has anything to do with thi...
- Andrei Alexandrescu (8/40) Jan 24 2013 I agree parallels with natural language are tenuous.
- Jacob Carlborg (7/8) Jan 25 2013 No, they're not. Perhaps in this particular case. But code is for humans...
- Jonathan M Davis (4/9) Jan 24 2013 We could add a __trait which detected whether a field was an actual vari...
- kenji hara (47/58) Jan 24 2013 OK, let's think.
- Jonathan M Davis (5/34) Jan 24 2013 I know, and I agree with it. But Andrei is pushing for removing @propert...
- kenji hara (3/6) Jan 24 2013 I'd like to argue that we should keep @property attribute.
- mist (27/27) Jan 25 2013 OK, it has become difficult to follow all thread (newsgroups are
- eles (14/14) Jan 25 2013 On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
- Simen Kjaeraas (7/21) Jan 25 2013 But setting the hours field to 28 is natural? While I want all
- eles (11/18) Jan 25 2013 See this answer here:
- Rob T (7/28) Jan 25 2013 You can easily wrap all of your functions in a try catch block
- Jonathan M Davis (10/32) Jan 25 2013 And why wouldn't setters be able to throw. Why on earth would you do oth...
- eles (13/30) Jan 25 2013 You are right. In fact, just after I post the message, I was hit
- Jonathan M Davis (16/31) Jan 25 2013 Except that variable assignments _can_ throw, because opAssign could thr...
- Jacob Carlborg (6/19) Jan 26 2013 One of the points of properties is to have a field with validation. To
- H. S. Teoh (90/108) Jan 25 2013 I've refrained so far from participating in this thread, but maybe it's
- mist (7/8) Jan 25 2013 Sound base that avoid discussion of controversial topics :) Looks
- Jonathan M Davis (22/32) Jan 25 2013 So, you're arguing that @property shouldn't be usable on anything but me...
- mist (11/12) Jan 25 2013 I am not going to argue anything, I am just asking _how_ they are
- H. S. Teoh (35/63) Jan 25 2013 This should behave as though you wrote this:
- Johannes Pfau (7/30) Jan 25 2013 Only if the getter is marked as const. We can discuss if that should be
- Johannes Pfau (3/23) Jan 25 2013 Ah you fooled me! There is only a setter in the first example!
- Adam Wilson (9/114) Jan 25 2013 ++
- Johannes Pfau (5/8) Jan 25 2013 3 or more arguments. UFCS properties have 2 arguments:
- H. S. Teoh (21/33) Jan 25 2013 [...]
- Dmitry Olshansky (11/116) Jan 25 2013 Good summary of what property should do. Let's just not forget that
- Jonathan M Davis (10/12) Jan 25 2013 [snip]
- Jonathan M Davis (9/11) Jan 25 2013 [snip]
- Zach the Mystic (40/40) Jan 25 2013 Here are my two cents:
- Timon Gehr (5/14) Jan 25 2013 No, you can definitely have ambiguity without optional parentheses.
- Zach the Mystic (5/25) Jan 25 2013 Actually, you're right. I meant: Optional parentheses as a
- Zach the Mystic (3/7) Jan 25 2013 Actually, that's ambiguous too. My English language statement.
- Jesse Phillips (2/7) Jan 25 2013 4, we are talking about D not C.
- luka8088 (14/26) Jan 26 2013 Maybe one possible issue to note. I am sorry if someone already noted
- Adam D. Ruppe (16/16) Jan 27 2013 I was just working on some work code and noticed this line that I
- Jonathan M Davis (13/36) Jan 27 2013 I think that one of two things would be likely to happen were @property ...
- Steven Schveighoffer (27/39) Jan 27 2013 Disagree. @property serves a very good purpose -- specifying intent. I...
- H. S. Teoh (7/39) Jan 27 2013 [...]
- Timon Gehr (2/11) Jan 28 2013 This proposal unfortunately does not work too well because of UFCS.
- Steven Schveighoffer (12/26) Jan 28 2013 As many have stated in the past, UFCS getter properties can annotate the...
- Jacob Carlborg (12/18) Jan 28 2013 I think @property adds clarity and shows intent. For example, now that
- eles (4/6) Jul 19 2013 Progressively, I start considering this as a not-so-bad idea.
- Stian Pedersen (11/11) Aug 10 2013 To add to the mess - or maybe suggest a new approach, what about:
- Stian Pedersen (1/1) Aug 10 2013 Missing an int before foo_ there.
- Borislav Kosharov (34/46) Aug 10 2013 I like this. It is something like in Ruby. And Ruby also has some
- BLM768 (5/17) Aug 10 2013 The problem with this approach is that the getter is still
- BLM768 (13/35) Aug 10 2013 Sorry; message got cut off when I tried to insert a tab and then
- JS (25/28) Aug 10 2013 Here is my mindless proposal after reading some of the posts.
- Iain Buclaw (6/21) Aug 10 2013 Might be wrong "cause I've only spent 5 minutes looking at it severall
- John Colvin (95/97) Aug 10 2013 My 2 cents on this, very late in the day. Sorry for the essay,
- Jason den Dulk (124/124) Aug 11 2013 Part 1 - Ordinary Functions (the rewrite rules)
This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.
Jan 24 2013
On 2013-01-24 09:34, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics.What do you mean by: "overloads for ()"?3. Parens are required for calling delegates or function pointers. 4. No more property.So: void delegate () foo (); foo() // would call the delegate ? -- /Jacob Carlborg
Jan 24 2013
On 1/24/2013 12:57 AM, Jacob Carlborg wrote:I mean there are no f(...) and f(U,T) overloads.only happens if f is a function that only has overloads for () and (one argument). No variadics.What do you mean by: "overloads for ()"?Yes.3. Parens are required for calling delegates or function pointers. 4. No more property.So: void delegate () foo (); foo() // would call the delegate ?
Jan 24 2013
On 1/24/13 3:57 AM, Jacob Carlborg wrote:On 2013-01-24 09:34, Walter Bright wrote:That means there must be two overloads of f exactly: T f(); f(T);This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics.What do you mean by: "overloads for ()"?Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate Andrei3. Parens are required for calling delegates or function pointers. 4. No more property.So: void delegate () foo (); foo() // would call the delegate ?
Jan 24 2013
On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegateI generic code, bugs I predict !
Jan 24 2013
On 1/24/13 11:43 AM, deadalnix wrote:On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:I agree it's something one must mind. AndreiYes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegateI generic code, bugs I predict !
Jan 24 2013
On 1/24/2013 8:43 AM, deadalnix wrote:On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:I would also count: f(some tuple) as requiring () even if "some tuple" expands to zero arguments. This should resolve issues with generic code.Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegateI generic code, bugs I predict !
Jan 24 2013
On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:On 1/24/13 3:57 AM, Jacob Carlborg wrote:How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.void delegate () foo (); foo() // would call the delegate ?Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
Jan 24 2013
On 1/24/13 12:15 PM, Peter Alexander wrote:On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:Agreed. This is a good litmus test. One option we had in mind was to still keep property for disambiguating such cases. AndreiOn 1/24/13 3:57 AM, Jacob Carlborg wrote:How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.void delegate () foo (); foo() // would call the delegate ?Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
Jan 24 2013
On Thursday, 24 January 2013 at 18:17:48 UTC, Andrei Alexandrescu wrote:Agreed. This is a good litmus test. One option we had in mind was to still keep property for disambiguating such cases.It seems we've gone full circle. Tends to happen when you try to fix 3 wrong turns with a 4th wrong turn :)
Jan 24 2013
Thinking about it, this isn't quite a full circle. It does improve a bit. If we aren't going dip21, how about: === Everything stays the way it is now, except: * if a property is called with parens, they always apply to the return value * -property hopefully dies. === I don't really like it, it leaves a number of problems behind... but that would be an improvement on the status quo. I don't hate it. So: alias void delegate() Callable; Callable nonprop(); property Callable prop(); Callable returned = nonprop; // ok, the parens are optional Callable returned = nonprop(); // ok, nonprop() just calls nonprop like any other function Callable returned = prop; // ok, no parens still calls, just like before Callable returned = prop(); // NOT GOOD: the () applies to the Callable (which returns void), not prop, because prop has property BTW nonprop()(); // calls the Callable (this expression returns void) prop()(); // nonsense (prop() returns void, which is not callable) --- int nonprop(); property int prop(); int returned = nonprop; // fine, optional parens int returned = nonprop(); // fine int returned = prop; // fine, we just call prop int returned = prop(); // NO GOOD: the () always applies to the return value, which in this case is int, which is not callable
Jan 24 2013
On 1/24/13 1:37 PM, Adam D. Ruppe wrote:Thinking about it, this isn't quite a full circle. It does improve a bit.Yes, I was about to write an email to destroy :o).If we aren't going dip21, how about: === Everything stays the way it is now, except: * if a property is called with parens, they always apply to the return value * -property hopefully dies. === I don't really like it, it leaves a number of problems behind... but that would be an improvement on the status quo. I don't hate it.Interesting, thanks. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 18:38:00 UTC, Adam D. Ruppe wrote:Thinking about it, this isn't quite a full circle. It does improve a bit. If we aren't going dip21, how about: === Everything stays the way it is now, except: * if a property is called with parens, they always apply to the return value * -property hopefully dies. ===If this means keeping the writeln = ""; then vote++. I've got no issues with the property syntax for methods. I actually want them. Why should properties only get the shorter syntax?I don't really like it, it leaves a number of problems behind... but that would be an improvement on the status quo. I don't hate it. So: alias void delegate() Callable; Callable nonprop(); property Callable prop(); Callable returned = nonprop; // ok, the parens are optional Callable returned = nonprop(); // ok, nonprop() just calls nonprop like any other function Callable returned = prop; // ok, no parens still calls, just like before Callable returned = prop(); // NOT GOOD: the () applies to the Callable (which returns void), not prop, because prop has property BTW nonprop()(); // calls the Callable (this expression returns void) prop()(); // nonsense (prop() returns void, which is not callable) --- int nonprop(); property int prop(); int returned = nonprop; // fine, optional parens int returned = nonprop(); // fine int returned = prop; // fine, we just call prop int returned = prop(); // NO GOOD: the () always applies to the return value, which in this case is int, which is not callable
Jan 27 2013
On Sunday, 27 January 2013 at 10:30:41 UTC, sclytrack wrote:On Thursday, 24 January 2013 at 18:38:00 UTC, Adam D. Ruppe wrote:Also since you can't overload property opDispatch and opDispatch at the same time without knowing all the property names or method names at compile time you can use the opDispatch for everything if the methods have a property like syntax.Thinking about it, this isn't quite a full circle. It does improve a bit. If we aren't going dip21, how about: === Everything stays the way it is now, except: * if a property is called with parens, they always apply to the return value * -property hopefully dies. ===If this means keeping the writeln = ""; then vote++. I've got no issues with the property syntax for methods. I actually want them. Why should properties only get the shorter syntax?
Jan 27 2013
On 1/24/2013 10:17 AM, Andrei Alexandrescu wrote:On 1/24/13 12:15 PM, Peter Alexander wrote:Another option is f(args) always requires parens, even if args expands to 0 args.On Thursday, 24 January 2013 at 16:29:07 UTC, Andrei Alexandrescu wrote:Agreed. This is a good litmus test. One option we had in mind was to still keep property for disambiguating such cases.On 1/24/13 3:57 AM, Jacob Carlborg wrote:How about generic code? void callFunc(alias f, Args...)(Args args) { f(args); } void delegate() foo(); void delegate(int) bar(int x); callFunc!foo(); // calls delegate? callFunc!bar(0); // calls bar? Seems like a recipe for disaster.void delegate () foo (); foo() // would call the delegate ?Yes. a = foo; // fetch the delegate b = foo(); // fetch and invoke the delegate
Jan 24 2013
On 1/24/2013 8:29 AM, Andrei Alexandrescu wrote:There could also be f(U), f(V), etc., just that the are all 0 or 1 arg.What do you mean by: "overloads for ()"?That means there must be two overloads of f exactly: T f(); f(T);
Jan 24 2013
On 2013-01-24 17:29, Andrei Alexandrescu wrote:That means there must be two overloads of f exactly: T f(); f(T);That's somewhat problematic since it won't allow chaining assignments: auto i = f = 3; We need to either allow: T f (); T f (T); Or implement some form of rewrite: f = 3; // calls setter auto i = f; // calls getter This is the preferred solution. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 09:12:47 UTC, Jacob Carlborg wrote:On 2013-01-24 17:29, Andrei Alexandrescu wrote:Assignation is right associative, so it is equivalent to : auto i = (f = 3); The setter is called.That means there must be two overloads of f exactly: T f(); f(T);That's somewhat problematic since it won't allow chaining assignments: auto i = f = 3; We need to either allow: T f (); T f (T); Or implement some form of rewrite: f = 3; // calls setter auto i = f; // calls getter This is the preferred solution.
Jan 25 2013
On 2013-01-25 10:16, deadalnix wrote:Assignation is right associative, so it is equivalent to : auto i = (f = 3); The setter is called.That's what I'm saying, the setter needs to be able to return something and not just void. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 13:18:47 UTC, Jacob Carlborg wrote:On 2013-01-25 10:16, deadalnix wrote:Hm, shouldn't it be processed like that: 1) evaluate "f = 3", setter called 2) evaluate "(f = 3)" -> evaluate "f" -> getter called 3) evaluate "auto i = ", setter called ?Assignation is right associative, so it is equivalent to : auto i = (f = 3); The setter is called.That's what I'm saying, the setter needs to be able to return something and not just void.
Jan 25 2013
On 2013-01-25 14:26, mist wrote:Hm, shouldn't it be processed like that: 1) evaluate "f = 3", setter called 2) evaluate "(f = 3)" -> evaluate "f" -> getter called 3) evaluate "auto i = ", setter called ?Yes, but why would a setter be called at step 3? -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 13:52:37 UTC, Jacob Carlborg wrote:On 2013-01-25 14:26, mist wrote:Was thinking about i setter, did not pay attention it is actually a new declaration :) Never mind.Hm, shouldn't it be processed like that: 1) evaluate "f = 3", setter called 2) evaluate "(f = 3)" -> evaluate "f" -> getter called 3) evaluate "auto i = ", setter called ?Yes, but why would a setter be called at step 3?
Jan 25 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.[...]4. No more property.You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
Jan 24 2013
On Thursday, 24 January 2013 at 09:03:45 UTC, anonymous wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:+1This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.[...]4. No more property.You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
Jan 24 2013
On 1/24/13 4:03 AM, anonymous wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This is a fix. AndreiThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.[...]4. No more property.You went half the way and now you're tired. Going back will be just as painful as going all the way. I say, keep property and fix it.
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.I agree, the cure seems to be ten times worse than the disease. It's consumed far more resources than it is worth. In my experience one of the main reasons that projects fail, is that nobody had the courage and humility to say, "this idea is a failure, we need to throw it away and do something completely different".Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.An example would make this easier to understand.2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.
Jan 24 2013
On 1/24/2013 1:11 AM, Don wrote:Jacob's should do.1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.An example would make this easier to understand.
Jan 24 2013
f = g; where it means f(g) is really ugly. I wouldn't like to see this. Also: void printSomeStuff() { //... } We are going to see code like this: printSomeStuff; // i think that's ugly. I suggested make parentheses optional only for UFC syntax. Also isn't it possible to allow property for functions that belong in a class/struct only?
Jan 24 2013
On Thursday, 24 January 2013 at 10:22:00 UTC, Minas Mina wrote:f = g; where it means f(g) is really ugly. I wouldn't like to see this. Also: void printSomeStuff() { //... } We are going to see code like this: printSomeStuff; // i think that's ugly. I suggested make parentheses optional only for UFC syntax. Also isn't it possible to allow property for functions that belong in a class/struct only?property also makes sense for global functions that need to emulate a run-time initialized static variable.
Jan 24 2013
On 1/24/2013 2:21 AM, Minas Mina wrote:We are going to see code like this: printSomeStuff; // i think that's ugly.Eeeyup. As for it being 'ugly', yes, it is a bit unsettling to us old time C programmers, but I think we can get used to it in short order. You can still add the () if you prefer.I suggested make parentheses optional only for UFC syntax.The simpler the rules are, the more likely they are to work.Also isn't it possible to allow property for functions that belong in a class/struct only?I want to get rid of property. It's an eyesore.
Jan 24 2013
Walter Bright wrote:I want to get rid of property. It's an eyesore.Yes! And on falling flat on that please rethink uglinesses like `writefln'. Such mangling of values of parameters into the identifiers of procedures might kill maintainability. Or: is everyone able to "see" the values hidden in several of such appendices coming from several libraries written by several coders? writefln, seefln, grabfln, killfln! `write( format="%s", someExpression, eol);' is in fact longer than `writefln( "%s", someExpression);' Really? -manfred
Jan 24 2013
On 24/01/2013 11:48, Manfred Nowak wrote:And on falling flat on that please rethink uglinesses like `writefln'. Such mangling of values of parameters into the identifiers of procedures might kill maintainability. Or: is everyone able to "see" the values hidden in several of such appendices coming from several libraries written by several coders? writefln, seefln, grabfln, killfln! `write( format="%s", someExpression, eol);' is in fact longer than `writefln( "%s", someExpression);'How about: write!"%s\n" = someExpression; :-p Seriously, it would be nice to have a compile-time checked format string for writefln.
Jan 24 2013
On Thu, Jan 24, 2013 at 4:53 PM, Nick Treleaven <ntrel-public yahoo.co.uk> wrote:write!"%s\n" = someExpression; :-p Seriously, it would be nice to have a compile-time checked format string for writefln.I made a stab at it in a template tutorial that can be found on github: https://github.com/PhilippeSigaud/D-templates-tutorial You can grab the pdf, it's on section 5.11, p. 168 (Statically-Checked Writeln) Use example:
Jan 24 2013
Philippe Sigaud wrote:cwritefln!"For sampleCough! `cfln' would eliminate the five letters `write'. For which purpose are they needed? Seriously, without some guarentee that `!"' starts a compile time checked string---and a defined metalanguage for describing compile time checking of compile time checked strings---close to every coding project will become an unmaintanable mess of DSL implementations "on the fly". The code you supplied on pages 170 to 171 is a good example for this forsight: please declare how much time an average member of an intended group of maintenance coders will need to grab the content of your idea. And of course declare the minimal skills all members of this group must have. -manfred
Jan 24 2013
On Fri, Jan 25, 2013 at 4:47 AM, Manfred Nowak <svv1999 hotmail.com> wrote:Philippe Sigaud wrote::) Yes, I agree.cwritefln!"For sampleCough! `cfln' would eliminate the five letters `write'. For which purpose are they needed?Seriously, without some guarentee that `!"' starts a compile time checked string---and a defined metalanguage for describing compile time checking of compile time checked strings---close to every coding project will become an unmaintanable mess of DSL implementations "on the fly".Well, the string-formatting DSL is well known. I don't think someone would be that distressed by its use.The code you supplied on pages 170 to 171 is a good example for this forsight: please declare how much time an average member of an intended group of maintenance coders will need to grab the content of your idea. And of course declare the minimal skills all members of this group must have.Such hate... Keep cool and please give us your own code and preferred solution to compile-time formatting string checking.
Jan 25 2013
Philippe Sigaud wrote:Such hate...No hate. Just knowledge out of experience.please give us your own code and preferred solution to compile-time formatting string checking.I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding. I am sure that your "stab at it" does not show any intent to approach the general problem. -manfred
Jan 25 2013
And what's the solution, for you? Using strings as DSL is somewhat common in D. As for DSL, well, I have a parser generator project here (https://github.com/PhilippeSigaud/Pegged), and I recently added the capacity to add new rules to a grammar at runtime and modify the resulting parse tree. I also used the existent, but unused macro keyword in D to get source code that can define its own subsequent grammar and parse tree transformations. Oh, and grammars can call one another, so adding a new sublanguage to a parent language is doable (I use this from time to time). I still have weeks fo work on this to have it reach the level I want, but I did not hit any wall up to now. So adding clean-looking DSL can be done in D, I think.please give us your own code and preferred solution to compile-time formatting string checking.I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding.I am sure that your "stab at it" does not show any intent to approach the general problem.No, indeed :) Since it's a recurring question here, I just showed it could be done. It's also a simple example of what can be done with D meta-programming capacities.
Jan 25 2013
On 1/26/13 2:50 AM, Philippe Sigaud wrote:As for DSL, well, I have a parser generator project here (https://github.com/PhilippeSigaud/Pegged), and I recently added the capacity to add new rules to a grammar at runtime and modify the resulting parse tree. I also used the existent, but unused macro keyword in D to get source code that can define its own subsequent grammar and parse tree transformations. Oh, and grammars can call one another, so adding a new sublanguage to a parent language is doable (I use this from time to time). I still have weeks fo work on this to have it reach the level I want, but I did not hit any wall up to now. So adding clean-looking DSL can be done in D, I think.Looking forward to your talk? :o) AndreiI am sure that your "stab at it" does not show any intent to approach the general problem.No, indeed :) Since it's a recurring question here, I just showed it could be done. It's also a simple example of what can be done with D meta-programming capacities.
Jan 26 2013
On 01/26/13 08:50, Philippe Sigaud wrote:I think his point was that inventing a custom dsl for everything does not scale. And he's of course right. Having one, or at most a few, common "std" dsls, plus ability do define custom ones is enough. But the "std" ones must be able to handle 95%+ of cases. So that everyone does not need to learn a set of custom per-site and/or per-project dsls. BTW, the std compile-time string formatting "dsl" is not only checkable, but can relatively easily be parsed at CT; the compiler will then do the rest. So there's really no point in using such a CT checker - if the string can be checked then it can also be handled directly, skipping any runtime parsing overhead completely.And what's the solution, for you? Using strings as DSL is somewhat common in D.please give us your own code and preferred solution to compile-time formatting string checking.I am not interested in formatting at all. I wrote about the general problem to incorporate expectable many DSL's into one big source base, as D is intended to serve large scale coding.As for DSL, well, I have a parser generator project here (https://github.com/PhilippeSigaud/Pegged), and I recently added the capacity to add new rules to a grammar at runtime and modify the resulting parse tree. I also used the existent, but unused macro keyword in D to get source code that can define its own subsequent grammar and parse tree transformations. Oh, and grammars can call one another, so adding a new sublanguage to a parent language is doable (I use this from time to time). I still have weeks fo work on this to have it reach the level I want, but I did not hit any wall up to now. So adding clean-looking DSL can be done in D, I think.Yes, this is possible, and desirable, to avoid "polluting" the main language with certain "features". However it's likely not enough, as there are aspects of D which make pure macro/dsl solutions not as simple as they could be (consider static-foreach). Your inline, parse-time, grammar extensions only work when the parser runs at CT, so the performance issues remain, right? Still, sounds interesting; and could be enough to explore the trickier cases and identify further problems. Must find time to play with it. Is that feature already in the repo? artur
Jan 26 2013
On 01/26/13 11:46, Artur Skawina wrote:identify further problems. Must find time to play with it. Is that feature already in the repo?Found it. Unfortunately the old compiler here can't handle newer D features and I can't really upgrade right now, so playing with pegged will have to wait. artur
Jan 26 2013
On 24/01/2013 17:04, Philippe Sigaud wrote:On Thu, Jan 24, 2013 at 4:53 PM, Nick Treleaven <ntrel-public yahoo.co.uk> wrote:Yes, I wish that was in Phobos ;-) In fact, couldn't cwritefln just be a template overload of writefln? The string value parameter may be enough to distinguish it from the runtime version.write!"%s\n" = someExpression; :-p Seriously, it would be nice to have a compile-time checked format string for writefln.I made a stab at it in a template tutorial that can be found on github: https://github.com/PhilippeSigaud/D-templates-tutorial You can grab the pdf, it's on section 5.11, p. 168 (Statically-Checked Writeln) Use example:
Jan 25 2013
Nick Treleaven wrote:write!"%s\n" = someExpression;Iff at all I prefer `write!someExpression= "%s\n";' Seriously, checking validity at execution time causes another sort of hiccoughs that should not be part of a language intended for large scale coding. -manfred
Jan 24 2013
On 2013-03-25 04:01, Manfred Nowak <svv1999 hotmail.com> wrote:Nick Treleaven wrote:From what I can see, Nick's solution allows compile time validity checking whereas yours does not. -- Simenwrite!"%s\n" = someExpression;Iff at all I prefer `write!someExpression= "%s\n";' Seriously, checking validity at execution time causes another sort of hiccoughs that should not be part of a language intended for large scale coding.
Jan 25 2013
Simen Kjaeraas wrote:[...]Seriouslywhereas yours does notTo me it is a syntactical change only. Where can I find the semantical change? And ... did you overlook the "seriously". -manfred
Jan 25 2013
Walter Bright wrote:4. No more property.yippee! -manfred
Jan 24 2013
I am probably I minority here but I liked the most strict -property version and it made a lot of sense to me. Rationale is simple: some().ufcs().chaining(); - this is just a minor syntax inconvenience anything; - this drives me crazy, there is no way to understand if this a no-op statement variable of function call with some side-effect I'd really like to have all function types to be obliged to use () and use property syntax only to those of property semantics (no side-effect variable getter/setter) But looking at other comments this does not seem popular :( Well, I can only hope for something simple and non-revolutionary then.
Jan 24 2013
On 01/24/13 12:50, mist wrote:But looking at other comments this does not seem popular :(Language design is not a popularity contest. artur
Jan 24 2013
On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:On 01/24/13 12:50, mist wrote:Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.But looking at other comments this does not seem popular :(Language design is not a popularity contest. artur
Jan 24 2013
On 01/24/13 14:46, mist wrote:On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:It's not merely "important"; it is essential. Those arguing for a "beatiful" UFCS syntax have not considered the consequences. Others see no point in arguing against obvious insanity; which skews the "popularity" numbers further. Just wait a year or so, until someone actually runs into the problems, and watch this discussion reincarnate. I can offhand think of three or four different ways to have a sane /and/ "beautiful" UFCS syntax, but even just discussing them would be a waste of time... For example, both of these are doable w/o involving property nor magic ()-less function calls; the second doesn't even require per-function annotations, at the cost of introducing another operator. iota(42, 2_000_000_000).filter!(a=>a&1).map!(to!string).take(10); iota(42, 2_000_000_000)->filter!(a=>a&1)->map!(to!string)->take(10); Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them. IOW, UFCS and property are not related, except the latter can currently be used as a workaround for missing functionality. arturOn 01/24/13 12:50, mist wrote:Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.But looking at other comments this does not seem popular :(Language design is not a popularity contest.
Jan 24 2013
On 1/24/13 9:47 AM, Artur Skawina wrote:Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them.You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore. Thanks, Andrei
Jan 24 2013
On 01/24/13 19:05, Andrei Alexandrescu wrote:On 1/24/13 9:47 AM, Artur Skawina wrote:You're more than welcome to produce counterevidence, or ignore the arguments, for whatever reasons. Ad hominems won't work, not only because I don't take this personally, but because I'm probably the person most willing/likely to discuss any relevant issues around here (I wish there was more like us (ie me)). Trying to make arguments you don't like go away and silencing the messenger is your MO. Please don't do that anymore. Not because I ask you to, but because it does harm the language, and the "community". Trying to at least understand the other point of view and reflecting a bit can be very enlightening. Who knows, you might even learn something new. Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker. This is an example of the kind of abuse of parens-less calls that an unsuspecting programmer shouldn't have to deal with. Sure, in this case it's simple enough, but in more complex scenarios, where the 'inorder' field/method/ufcs definition is not readily available, it would be extremely misleading. It's not reasonable to expect everyone reading the code to check every single object field access, just in case the previous coder decided that the source looked "cuter" w/o the '()'. artur [1] This isn't meant to single out Timon in any way; it's just a recent public code example I happened to remember. I would consider Timon one of the most helpful and knowledgeable people here - thanks for all the help and arguments, even the ones where we disagree, btw.Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them.You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
Jan 24 2013
On 1/24/13 2:03 PM, Artur Skawina wrote:On 01/24/13 19:05, Andrei Alexandrescu wrote:Good quality discussion is always welcome. I have specifically opposed a specific rhetoric, not a person, so "ad hominem" is inappropriate here.On 1/24/13 9:47 AM, Artur Skawina wrote:You're more than welcome to produce counterevidence, or ignore the arguments, for whatever reasons. Ad hominems won't work, not only because I don't take this personally, but because I'm probably the person most willing/likely to discuss any relevant issues around here (I wish there was more like us (ie me)).Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them.You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".Please don't do that anymore.I will always protest the rhetoric mentioned, sorry.Not because I ask you to, but because it does harm the language, and the "community". Trying to at least understand the other point of view and reflecting a bit can be very enlightening. Who knows, you might even learn something new.Sarcasm is always appreciated :o). On a serious note, it's a bit assuming to conclude that disagreeing with something must be caused by not understanding it. This is not rocket science. The points involved are understood. That doesn't entail agreement.Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker.How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me. Andrei
Jan 24 2013
On 01/24/2013 09:13 PM, Andrei Alexandrescu wrote:...There is no bug.Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker.How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
Jan 24 2013
On 01/24/13 21:13, Andrei Alexandrescu wrote:On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".Bug? In Timon's code? Impossible. :) No, this is just about syntax. Some functions are not suitable for calling w/o '()', and the choice needs to stay with the callee. But the distinction is "sane/insane" for a reason - there's judgment, taste and common sense involved. Trusting every programmer to get it right won't work, unfortunately. arturHaving said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker.How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
Jan 24 2013
On 1/25/13 2:12 AM, Artur Skawina wrote:On 01/24/13 21:13, Andrei Alexandrescu wrote:Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".I'd say "sane/insane" is pushing it. AndreiBug? In Timon's code? Impossible. :) No, this is just about syntax. Some functions are not suitable for calling w/o '()', and the choice needs to stay with the callee. But the distinction is "sane/insane" for a reason - there's judgment, taste and common sense involved. Trusting every programmer to get it right won't work, unfortunately.Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker.How about this: insert the parens and then demonstrate how the bug is easier to spot. Wasn't any easier for me.
Jan 24 2013
On 01/25/13 08:39, Andrei Alexandrescu wrote:On 1/25/13 2:12 AM, Artur Skawina wrote:Hmm, I can see how you could view this as an ad hominem, given that definition, but it's not meant to be one and actually isn't - it has no bearing on the property nor ()-less calls issues; this is just about the process. Remember how you originally replied to my message, after removing everything but one sentence, which was clearly both a summary of my subjective position and deliberately phrased in a way to encourage at least some consideration wrt $subject by others making a decision. This isn't a new discussion, there's no need to restate the same arguments, from other threads, over and over again. Your response didn't provide any counterargument nor opinion on the subject; instead you chose to complain about the form and - I have no choice but to assume deliberately - misinterpret it. And asked me not to 'do that', in an attempt to manipulate the discussion. Crying "Ad Hominem!" now, after I point out that such tactics are not really helping to foster discussion, won't make it one, sorry. /I/ have no problem ignoring your comments, but others may not be as thick-skinned or not view D from the same perspective, and not willing to deal with that kind of arrogance. The number of D contributors is low enough, why drive potential ones away?On 01/24/13 21:13, Andrei Alexandrescu wrote:Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".Normally, I'd probably agree, but in the context of removing property, but not implementing correct accessors nor enforcing calling syntax "insane" is appropriate. It's "sane/insane", because absolute terms such as "right/wrong" would be too strong; there is a large subjective component to it. arturand the choice needs to stay with the callee. But the distinction is "sane/insane" for a reason - there's judgment, taste and common sense involved. Trusting every programmer to get it right won't work, unfortunately.I'd say "sane/insane" is pushing it.
Jan 25 2013
On 1/25/13 5:56 AM, Artur Skawina wrote:On 01/25/13 08:39, Andrei Alexandrescu wrote:How can that be seen as anything else? What definition do you have? You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.On 1/25/13 2:12 AM, Artur Skawina wrote:Hmm, I can see how you could view this as an ad hominem, given that definition,On 01/24/13 21:13, Andrei Alexandrescu wrote:Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".but it's not meant to be one and actually isn't - it has no bearing on the property nor ()-less calls issues; this is just about the process. Remember how you originally replied to my message, after removing everything but one sentence, which was clearly both a summary of my subjective position and deliberately phrased in a way to encourage at least some consideration wrt $subject by others making a decision.I kept the sentence that I had a reply for. The rest I understood and agreed with. Andrei
Jan 25 2013
Andrei Alexandrescu wrote:You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.At this point, the only difference between you and Nick S. is the frequency of four-letter words in your posts. It's a real pity, D could have been such a nice language, but with that kind of "leadership"... - John
Jan 25 2013
On 01/25/13 15:28, Andrei Alexandrescu wrote:On 1/25/13 5:56 AM, Artur Skawina wrote:No. Please don't try to reinterpret what I said, this is the second time you did this. But, like i said, I can see that you view it like that. Fact is that that comment had absolutely nothing to do with the argument itself - I was only replying to your response, which was unacceptable. So, yes, I am talking about what you did, but that does not automatically mean it's an ad hominem, otherwise any critical comment about how the conversation is handled by the other side would be. I did make that comment too generic, and for that I'll apologize - I really should have said that /it happens/, and not used a figure of speech that can reasonably be misunderstood. I should have reread and caught that, I'm sorry. I'm still saying that these types of responses, when uncalled for (at least I didn't say 'in a well defined language..."), but caused only by your dislike of the argument or form thereof, are inappropriate.On 01/25/13 08:39, Andrei Alexandrescu wrote:How can that be seen as anything else? What definition do you have? You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.On 1/25/13 2:12 AM, Artur Skawina wrote:Hmm, I can see how you could view this as an ad hominem, given that definition,On 01/24/13 21:13, Andrei Alexandrescu wrote:Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".I kept the sentence that I had a reply for. The rest I understood and agreed with.It contained examples showing how all '()' could be omitted within ufcs chains, except the last pair. That would be a reasonable compromise, make code concise and unambiguous to read, but I guess you don't agree that doing it like that would be enough. artur
Jan 25 2013
On Fri, 25 Jan 2013 02:39:15 -0500 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/25/13 2:12 AM, Artur Skawina wrote:"Ad hominem" *as a logical fallacy* is only applicable when the argument against the person is *intended* to prove something unrelated to the targeted person. For example, "Joe Schmo is a known asshole" *could* very easily be a logical fallacy. But it clearly *isn't* a fallacy if the speaker is using it to show: "Joe Schmo, your request to be a kindergarten teacher should be rejected." Artur was clearly making a side note about an unfortunate tendency in some of your posts that I've noticed as well. This was to make you aware of it and hopefully do it less. It was NOT, as you suggest, being put forth as evidence for Artur's property-related arguments.On 01/24/13 21:13, Andrei Alexandrescu wrote:Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.On 1/24/13 2:03 PM, Artur Skawina wrote:No, it's not - it's just stating the facts; this was not the first such incident.Trying to make arguments you don't like go away and silencing the messenger is your MO.Now that's what's called "ad hominem".
Jan 25 2013
On 01/24/2013 08:03 PM, Artur Skawina wrote:... Having said that, I'll elaborate on the sentence you quoted above. See for example Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the tree-walker. This is an example of the kind of abuse of parens-less calls that an unsuspecting programmer shouldn't have to deal with. Sure, in this case it's simple enough, but in more complex scenarios, where the 'inorder' field/method/ufcs definition is not readily available, it would be extremely misleading. It's not reasonable to expect everyone reading the code to check every single object field access, just in case the previous coder decided that the source looked "cuter" w/o the '()'. ...Uh... class Tree(T){ InOrder!T inorder; this(){inorder = InOrder!T(this); } Tree!T l,r; T v; } auto tree(T)(Tree!T l, T v, Tree!T r){ auto t = new Tree!T; t.l=l;t.r=r;t.v=v; return t; } auto tree(T)(T v){ return tree(Tree!T.init,v,Tree!T.init); } struct InOrder(T){ this(Tree!T c){container=c;} Tree!T container; InOrder* t; mixin Yield!(q{ if (container.l !is null){ for(t=[container.l.inorder].ptr;!t.empty;t.popFront()) yield t.front; } yield container.v; if (container.r !is null){ for(t=[container.r.inorder].ptr;!t.empty;t.popFront()) yield t.front; } },T); } //InOrder!T inorder(T)(Tree!T container){ return InOrder!T(container); }
Jan 24 2013
On Thursday, 24 January 2013 at 18:05:25 UTC, Andrei Alexandrescu wrote:On 1/24/13 9:47 AM, Artur Skawina wrote:Let me rephrase that in a proper way. Functional style is very painful right now. Function you pass as argument are executed implicitly, function as variable don't behave like native ones, and with the new proposal, it add confusion on the function returned. It is kind of dumb that D do not promote functional style as it has shown to solve many problems that arise right now.Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them.You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
Jan 24 2013
On 01/25/2013 03:44 AM, deadalnix wrote:On Thursday, 24 January 2013 at 18:05:25 UTC, Andrei Alexandrescu wrote:The main issue is horrible garbage collector performance for many small allocations. Syntactically we could do what scala does: scala> def fun()=2 fun: ()Int scala> fun : Int res0: Int = 2 scala> fun : (()=>Int) res1: () => Int = <function0>On 1/24/13 9:47 AM, Artur Skawina wrote:Let me rephrase that in a proper way. Functional style is very painful right now. Function you pass as argument are executed implicitly, function as variable don't behave like native ones, and with the new proposal, it add confusion on the function returned. It is kind of dumb that D do not promote functional style as it has shown to solve many problems that arise right now.Having ()-less function calls is just insane; if it isn't obvious to you why, you just haven't read enough code that (ab)uses them.You see, this is the kind of argument that I find very damaging to the conversation. It lacks any shred of material evidence, evokes emotion, manipulates the reader's opinion (framing them into incompetent/inexperienced if they disagree), and implies an appeal to authority. Please don't do that anymore.
Jan 24 2013
2013/1/25 deadalnix <deadalnix gmail.com>Functional style is very painful right now. Function you pass as argument are executed implicitly, function as variable don't behave like native ones, and with the new proposal, it add confusion on the function returned.I'd like to add a rule which forgotten to mention about optional parentheses for normal functions.1. Optional parentheses for normal functions should work shallowly IMO.1a. Optional parentheses for normal functions is just allowed for the getter usage. int foo(); foo(); // ok void bar(int); bar(1); // ok Kenji Hara
Jan 24 2013
Am Thu, 24 Jan 2013 14:46:32 +0100 schrieb "mist" <none none.none>:On Thursday, 24 January 2013 at 13:34:08 UTC, Artur Skawina wrote:+1 Just as you and Nick I also like consistent function calls much more. Properties only make sense if you have consistent function calls, but then they're essential. If we allow optional parenthesis the properties are pretty much useless.On 01/24/13 12:50, mist wrote:Well most discussions seems to flow around simple preference conflict of beautiful UFCS vs consistent function calls. And all compromises tend to explode in difficulty once delegates and function pointers are taken into consideration. I find consistent and unambiguous call syntax more important.But looking at other comments this does not seem popular :(Language design is not a popularity contest. artur
Jan 24 2013
On 1/24/13 6:50 AM, mist wrote:I am probably I minority here but I liked the most strict -property version and it made a lot of sense to me. Rationale is simple: some().ufcs().chaining(); - this is just a minor syntax inconvenienceIt becomes way uglier with templates: some!(e1)().ufcs!(e2)().chaining!(e3)(). In fact look at the code written by Nick in _favor_ of the parens. Self-destruction at its finest.anything; - this drives me crazy, there is no way to understand if thisI was amazed at how quickly I got used to it.a no-op statement variable of function call with some side-effect I'd really like to have all function types to be obliged to use () and use property syntax only to those of property semantics (no side-effect variable getter/setter) But looking at other comments this does not seem popular :( Well, I can only hope for something simple and non-revolutionary then.You'll still be able to use parens. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 17:49:18 UTC, Andrei Alexandrescu wrote:On 1/24/13 6:50 AM, mist wrote:I can hardly see any problems in your code sample. Syntax inconvenience means nothing when compared to semantic inconvenience. It is just matter of visual preferences after all, you can get used to it quite fast.I am probably I minority here but I liked the most strict -property version and it made a lot of sense to me. Rationale is simple: some().ufcs().chaining(); - this is just a minor syntax inconvenienceIt becomes way uglier with templates: some!(e1)().ufcs!(e2)().chaining!(e3)(). In fact look at the code written by Nick in _favor_ of the parens. Self-destruction at its finest.anything; - this drives me crazy, there is no way to understand if thisI was amazed at how quickly I got used to it....You'll still be able to use parens. AndreiYou see, contrary to UFCS chaining this is not habit or syntax issue. It is semantic one - I am loosing an ability to distinct data access from function call by simply looking at code. There is nothing I can get used to - in a sane design I have this info, in D I do not. You have been just shown a few very good examples regarding functions, returning delegates - it is exactly the case where it shines. Yes, I am able to use parens, but in _my_ code I also do not need -property or anything - I am C++ programmer after all, I can discipline myself to certain code style even without compiler help. But writing generic code and reading one of others... I am glad I have not had to do any high-order function generic processing yet.
Jan 24 2013
On 1/24/13 1:35 PM, mist wrote:You see, contrary to UFCS chaining this is not habit or syntax issue. It is semantic one - I am loosing an ability to distinct data access from function call by simply looking at code.This is the case with any property implementation. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 20:00:18 UTC, Andrei Alexandrescu wrote:On 1/24/13 1:35 PM, mist wrote:Not really. Good property usage is somewhat similar to unsafe cast usage - you say to others "Yes, I know what I am doing, please do not pay attention that this data is in fact function". The very point of properties is to be used almost indistinguishable from data and if this usage pattern fails - property author has lied and this is not really a property. And because of issues like "+=" it is rather difficult (if possible) to define good properties in D now.You see, contrary to UFCS chaining this is not habit or syntax issue. It is semantic one - I am loosing an ability to distinct data access from function call by simply looking at code.This is the case with any property implementation. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 21:06:02 +0100 "mist" <none none.none> wrote:Not really. Good property usage is somewhat similar to unsafe cast usage - you say to others "Yes, I know what I am doing, please do not pay attention that this data is in fact function". The very point of properties is to be used almost indistinguishable from data and if this usage pattern fails - property author has lied and this is not really a property.+1And because of issues like "+=" it is rather difficult (if possible) to define good properties in D now.+1
Jan 24 2013
On Thursday, 24 January 2013 at 18:35:08 UTC, mist wrote:Yes, I am able to use parens, but in _my_ code I also do not need -property or anything - I am C++ programmer after all, I can discipline myself to certain code style even without compiler help. But writing generic code and reading one of others... I am glad I have not had to do any high-order function generic processing yet.I always create dumb lambda to do so as going fully functional is too painful map!(a => foo(a)) instead of map!foo . That is really annoying.
Jan 24 2013
On 01/25/2013 03:48 AM, deadalnix wrote:On Thursday, 24 January 2013 at 18:35:08 UTC, mist wrote:And just as pointless.Yes, I am able to use parens, but in _my_ code I also do not need -property or anything - I am C++ programmer after all, I can discipline myself to certain code style even without compiler help. But writing generic code and reading one of others... I am glad I have not had to do any high-order function generic processing yet.I always create dumb lambda to do so as going fully functional is too painful map!(a => foo(a)) instead of map!foo . That is really annoying.
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions. -Bernard.
Jan 24 2013
Bernard Helyer:To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications.Sounds OK. Instead of adding a -property, why wasn't this done since the beginning? (The right switch to add was -noproperty, to disable the feature, because most people do not use switches). Bye, bearophile
Jan 24 2013
On 2013-01-24 13:35, bearophile wrote:Instead of adding a -property, why wasn't this done since the beginning?It would break tons of code. -- /Jacob Carlborg
Jan 24 2013
Jacob Carlborg:It would break tons of code.How much work does it take to change that makes and compilation scripts to compile that code using a "-noproperty" switch? I think this silly fear of breaking user code was one of the main causes of the failure of property in the first place. If you introduce a new feature, then you need to introduce it cleanly since the beginning, otherwise you will make a mess. So future D feature must be introduced in a much more clean way in future, or not introduced at all. Bye, bearophile
Jan 24 2013
On 2013-01-24 14:01, bearophile wrote:Jacob Carlborg:No one can answer that.It would break tons of code.How much work does it take to change that makes and compilation scripts to compile that code using a "-noproperty" switch?I think this silly fear of breaking user code was one of the main causes of the failure of property in the first place. If you introduce a new feature, then you need to introduce it cleanly since the beginning, otherwise you will make a mess. So future D feature must be introduced in a much more clean way in future, or not introduced at all.I agree with you but Walter is very afraid of breaking code. -- /Jacob Carlborg
Jan 24 2013
On 1/24/2013 5:42 AM, Jacob Carlborg wrote:I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 24 2013
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:On 1/24/2013 5:42 AM, Jacob Carlborg wrote:<rage>Please. Go to http://wiki.dlang.org/Release_Process . Read it. Answer the question "Hm, does having well-defined release process with long-term support versions help with instability of breaking changes?". And if answer is "no" then you probably should have contributed your opinion there for a long time, because it _should_ to.</rage> Really, all this backwards-compatibility talk is a crap. There is no way we can say current D design is final and solid and can be polished without any breaking changes. We should not argue about how bad breaking is. We should discus how to do those changes in the least harmful way.I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 24 2013
On 1/24/13 3:58 PM, mist wrote:Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:On 1/24/13 3:58 PM, mist wrote:Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Jan 24 2013
On 1/24/13 4:06 PM, mist wrote:On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:It was your second paragraph I quoted.On 1/24/13 3:58 PM, mist wrote:Do you read and answer only to the first sentence?Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. AndreiCan you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"?Clearly the design is imperfect.If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.My understanding is that we're working on such. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 21:23:53 UTC, Andrei Alexandrescu wrote:...Sorry Andrei, with all my due respect, you have a brilliant talent to answer something without actually stating any own position on topic. Please take a look to my answer to Walter: http://forum.dlang.org/post/lpdegnaygbiijuwddgpf forum.dlang.org I'd really like to understand your position too, because arguing about sentences leads nowhere.
Jan 25 2013
On Thursday, January 24, 2013 22:06:02 mist wrote:On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:The problem is that we have competing goals that we have to deal with 1. Fix any problems in the language so that its design is solid. 2. Avoid breaking people's code. with the perfect language when we're done, it doesn't matter much if no one's using it, and if we are forever breaking people's code, then they're not going to stick around. The trick is deciding when and how we need to and can get away with breaking code. And the longer it takes to solve major design flaws in the language which require breaking code, the more code we'll break when we do make the changes, and the more problems will have, which is one reason why it's so frustrating that it often takes quite a while to properly sort this sort of thing out. - Jonathan M DavisOn 1/24/13 3:58 PM, mist wrote:Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 13:26:11 -0800, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Thursday, January 24, 2013 22:06:02 mist wrote:I don't think we can fix property (or remove it) without breaking code. So I would plead with the community to accept that. This is a very important problem to fix. Obviously deciding how to proceed is going to be difficult but I don't think that we have copious amounts of time for the community to slug it out either. You either break properties or optional parens, either way creates problems. I would argue that removing property creates more problems than removing optional parens. One is a highly delicate surgical operation on the parser to handle all the new ambiguities, more documentation to explain, and more chances to the user to D the wrong (but still acceptable) thing, and requires large amounts code refactoring. The other is a simple find/replace in user code, with some simple changes to the parser. I will always vote for the less bug-prone path. Remove Optional Parens. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:The problem is that we have competing goals that we have to deal with 1. Fix any problems in the language so that its design is solid. 2. Avoid breaking people's code. we do end up with the perfect language when we're done, it doesn't matter much if no one's using it, and if we are forever breaking people's code, then they're not going to stick around. The trick is deciding when and how we need to and can get away with breaking code. And the longer it takes to solve major design flaws in the language which require breaking code, the more code we'll break when we do make the changes, and the more problems will have, which is one reason why it's so frustrating that it often takes quite a while to properly sort this sort of thing out. - Jonathan M DavisOn 1/24/13 3:58 PM, mist wrote:Do you read and answer only to the first sentence? Can you honestly say "D design is rock solid and correct, we will never be required to make any backwards-incompatible change"? If you check those evidences, it was never breaking code alone. It was breaking code AND lack of any sane process that allows to stick with acceptable release version for longer time. And I suggest to fix the right thing, not freeze specs and hope all problems will fade themselves.Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 21:40:01 UTC, Adam Wilson wrote:Remove Optional Parens.This has absolutely nothing to do with properties because properties are data fields, NOT functions. http://forum.dlang.org/post/fpbvfpvnjtgqbganqece forum.dlang.org
Jan 24 2013
On Thu, 24 Jan 2013 13:41:55 -0800, Adam D. Ruppe <destructionator gmail.com> wrote:On Thursday, 24 January 2013 at 21:40:01 UTC, Adam Wilson wrote:From the compilers standpoint they are functions. It must be so. That's how they're implemented. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/Remove Optional Parens.This has absolutely nothing to do with properties because properties are data fields, NOT functions. http://forum.dlang.org/post/fpbvfpvnjtgqbganqece forum.dlang.org
Jan 24 2013
On Thursday, 24 January 2013 at 21:44:12 UTC, Adam Wilson wrote:From the compilers standpoint they are functions. It must be so. That's how they're implemented.No, they are property functions. That's important because it lets them be rewritten at the usage point, similarly to operator overloading and various other tricks in the language, which also doesn't care about function call syntax, despite being implemented as functions. I was messing with the compiler a while ago to make my vision work. Got about 90% there, but it got too messy when doing setters. Only made 5 changes: DsymbolExp::semantic if the function this references was declared as a property, rewrite the symbol to be a call expression Thus "bar", if bar was declared as property, is rewritten into "(bar())" and the rest carries on normally. (So if the whole expression was "bar().foo", the rest of the compiler sees it as "(bar())().foo" and reacts accordingly.) DotVarExp::semantic ditto, but for members instead And the others were trying to make it work for setters in BinExp, AssignExp, and a filthy hack in CallExp itself to find the setter given a getter. The getter change, about 10 lines of code in dmd, was a success. The setters are where I tripped up and couldn't get it to work right, but this is probably because I'm not a dmd master, not because it is impossible.
Jan 24 2013
On Thursday, 24 January 2013 at 21:00:32 UTC, Andrei Alexandrescu wrote:On 1/24/13 3:58 PM, mist wrote:If you or Walter think that D is somehow stable or backward compatible, you must both be very high on drugs. Yes that is an ad hominem. Let me tell you a story. This story take place one month ago. A guy (me) get the news released version of the compiler. After all, he badly needs it as bugs in the previous cause the GC to misbehave in very scary ways. First, some language specs have changed, so his code is broken. But hey, that is to be expected and so the guy fix his code. A bug is discovered in the compiler, it is a regression, and it make the guy's code, once fixed, impossible to compile with 2.061 AT ALL. Hopefully a brave knight (Kenji) cam to fight the monstrous compiler and finally get it to compile the code it should have compiled from day 1. The guy now use a custom patched version of the compiler. No revision of the compiler is released at this point, but worse, the guy's code now trigger some other bugs into 2.061 (but not in his patched version). The guy can't do D on his mac anymore as he have no clue how to do the setup for his patched compiler. After all, he is not really an apple guy. Note that was already using a custom compiler before 2.060 as 2.059 already have blocking bugs for me. D is nothing even remotely close to stable. D introduce breaking change with EVERY new release. Worse, D has no sane way to introduce such breaking change in a sane way. And suddenly, this is an issue ?Really, all this backwards-compatibility talk is a crap.There's just a lot of evidence that suggests the contrary. Clearly we don't want or like to be conservative, but apparently we need to.
Jan 24 2013
On 1/24/2013 12:58 PM, mist wrote:<rage>Please. Go to http://wiki.dlang.org/Release_Process . Read it. Answer the question "Hm, does having well-defined release process with long-term support versions help with instability of breaking changes?". And if answer is "no" then you probably should have contributed your opinion there for a long time, because it _should_ to.</rage> Really, all this backwards-compatibility talk is a crap. There is no way we can say current D design is final and solid and can be polished without any breaking changes. We should not argue about how bad breaking is. We should discus how to do those changes in the least harmful way.Having a release process does not remove the pain of breaking changes that make users miserable because their older code no longer compiles.
Jan 24 2013
On Thursday, 24 January 2013 at 22:45:52 UTC, Walter Bright wrote:Having a release process does not remove the pain of breaking changes that make users miserable because their older code no longer compiles.Beg my pardon, it is very ignorant position. It assumes user is some kind of stubborn creature that is scared of any spec changes. But it is not really the case. Users are not afraid of compiler release breaking their code - they are afraid of not having a single compiler version that both is stable enough and works for their code. And that it is very different. It is fine to break code in release if you still provide bug-fixes to some older version that may be recommended for usage until time to fix code base is taken. And this is exactly where good release process shines, it is single most important reason to have it. To sum up my position: 1) D spec is imperfect 2) Breaking change are inevitable 3) Saying "breaking changes" are bad means hiding the problem 4) It is better to focus on process to minimize breaking changes damage than rant about how bad they are 5) Leaving feature badly designed for years with no hope to change is worse than breaking code. I'd really like to read your position on _all_ of those statements, because we are running circles here.
Jan 25 2013
Also I need to remind you that we break code all the time with big fixes, literally every release. And end user does not care how reasonable breaking it is, they are all the same: time needed to update the code base. We need to admit that breaking is inevitable and go forward from there to fix real solvable problems.
Jan 25 2013
On Thursday, 24 January 2013 at 22:45:52 UTC, Walter Bright wrote:Having a release process does not remove the pain of breaking changes that make users miserable because their older code no longer compiles.What about providing a tool to automatically perform the transform necessary to fix the code (w.r.t. the breaking change)? That should be feasible in many cases, and there are languages that have gone down this route already (Python 3 partially, Go fully, if I'm not mistaken). gath
Jan 25 2013
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:On 1/24/2013 5:42 AM, Jacob Carlborg wrote:That is why semantic needs to be clean. Semy hacky stuff ends up causing trouble and we either have to live with it or break code.I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 24 2013
On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:On 1/24/2013 5:42 AM, Jacob Carlborg wrote:I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 25 2013
On Friday, 25 January 2013 at 09:49:29 UTC, Don wrote:...++ It feels that "breaking code" has become some kind of scary ghost that is just being afraid of instead of some kind of analysis-based approach.
Jan 25 2013
On 1/25/13 4:49 AM, Don wrote:On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:TDPL did exactly that. For example it doesn't mention foreach_reverse or lazy. Far as I know that didn't make a difference. AndreiOn 1/24/2013 5:42 AM, Jacob Carlborg wrote:I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 25 2013
On Friday, 25 January 2013 at 14:18:06 UTC, Andrei Alexandrescu wrote:TDPL did exactly that. For example it doesn't mention foreach_reverse or lazy. Far as I know that didn't make a difference.Wise move !
Jan 25 2013
25-Jan-2013 13:49, Don пишет:On Thursday, 24 January 2013 at 20:52:10 UTC, Walter Bright wrote:+1 -- Dmitry OlshanskyOn 1/24/2013 5:42 AM, Jacob Carlborg wrote:I don't believe that is true. Remember when 'bit' was removed from the language? It didn't cause any complaints at all. This attitude is very harmful. Our real problem is that we're not making promises about what we won't change. When we haven't made such promises, we then become fearful of changing *anything*. Then we bend over backwards to avoid changing things that actually nobody cares about. This is a recipe for locking bugs into the language forever. Instead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.I agree with you but Walter is very afraid of breaking code.The history of what happens when D code breaks because of language changes is not a happy one.
Jan 25 2013
On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky wrote:I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rtInstead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.+1
Jan 25 2013
On Friday, 25 January 2013 at 18:03:54 UTC, Rob T wrote:On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky wrote:+1 The language has reached a point where bugs in the spec are more important than bugs of the implementation. In fact many difficult bugs in the implementation are rooted in spec issues.I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rtInstead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.+1
Jan 27 2013
On Sunday, 27 January 2013 at 09:51:04 UTC, SomeDude wrote:On Friday, 25 January 2013 at 18:03:54 UTC, Rob T wrote:I went to stress the "followed" part. I.e. we do have quite a good release process description on wiki with some related parts also mentioned. But if it is followed as good as upon 2.061, it makes not difference.On Friday, 25 January 2013 at 17:52:12 UTC, Dmitry Olshansky wrote:+1 The language has reached a point where bugs in the spec are more important than bugs of the implementation. In fact many difficult bugs in the implementation are rooted in spec issues.I agree with this completely, but we cannot do it until there's a full implementation of a reasonably designed and followed development and release process that includes the language specification. --rtInstead, we should be trying to continuously expand the things we guarantee will continue to work. Ideally we would be precise about the things that are likely to change, and which we don't currently guarantee.+1
Jan 27 2013
On 1/24/13 8:01 AM, bearophile wrote:I think this silly fear of breaking user code was one of the main causes of the failure of property in the first place.No. property is bad design, pure and simple. It's great that we're acknowledging that. Andrei
Jan 24 2013
On Thursday, 24 January 2013 at 12:53:45 UTC, Jacob Carlborg wrote:On 2013-01-24 13:35, bearophile wrote:And yet it must have been done at some point. With some year-ahead announcement or anything like that, but it was a horrible design error in first place which needs to be fixed.Instead of adding a -property, why wasn't this done since the beginning?It would break tons of code.
Jan 24 2013
mist:but it was a horrible design error in first place which needs to be fixed.Don't forget that our discussions in this thread are mostly academic :-) Bye, bearophile
Jan 24 2013
On 2013-01-24 14:01, mist wrote:And yet it must have been done at some point. With some year-ahead announcement or anything like that, but it was a horrible design error in first place which needs to be fixed.Yes, it was a horrible design error but it didn't break any code because the -property flag is optional. -- /Jacob Carlborg
Jan 24 2013
On Thursday, 24 January 2013 at 13:43:41 UTC, Jacob Carlborg wrote:On 2013-01-24 14:01, mist wrote:Design error was to not force "-property" since the very beginning. Now good decisions are kind of doomed to break code because restrictions were (and still are) too lax and a lot of inconsistent code is somewhere out there. This is exactly why I voted for LTS + rolling-release model. D is still far from the point where design specs can be frozen and breaking code prohibited. Those still have mistakes.And yet it must have been done at some point. With some year-ahead announcement or anything like that, but it was a horrible design error in first place which needs to be fixed.Yes, it was a horrible design error but it didn't break any code because the -property flag is optional.
Jan 24 2013
On Thursday, 24 January 2013 at 12:13:57 UTC, Bernard Helyer wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history.I would say: kill -property, not property.
Jan 24 2013
Absolutely agree. I think it's pretty weak to say property is a monster/failure, and then Finish the deed! Your set of proposed rules are far more complex and non-uniform... what is the advantage to that complexity? On 24 Jan 2013 19:15, "Bernard Helyer" <b.helyer gmail.com> wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions. -Bernard.
Jan 24 2013
On 1/24/13 7:13 AM, Bernard Helyer wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality. AndreiThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions.
Jan 24 2013
On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu wrote:No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality.The simple(r) explanation is: The current *implementation* is broken. David
Jan 24 2013
On 1/24/13 12:54 PM, David Nadlinger wrote:On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu wrote:Simpler doesn't make it true. AndreiNo. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality.The simple(r) explanation is: The current *implementation* is broken.
Jan 24 2013
On Thursday, January 24, 2013 18:54:00 David Nadlinger wrote:On Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu wrote:Exactly. Most of the problems with property stem from the fact that it's not implemented properly, particularly with regards to the -property flag. - Jonathan M DavisNo. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality.The simple(r) explanation is: The current *implementation* is broken.
Jan 24 2013
On 1/24/13 2:14 PM, Jonathan M Davis wrote:On Thursday, January 24, 2013 18:54:00 David Nadlinger wrote:That is because it's not well defined. AndreiOn Thursday, 24 January 2013 at 17:51:32 UTC, Andrei Alexandrescu wrote:Exactly. Most of the problems with property stem from the fact that it's not implemented properly, particularly with regards to the -property flag.No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't; (b) property adds noise for everybody for the sake of a corner case (functions returning delegates); (c) the property discipline failed to align itself in any way with better code quality.The simple(r) explanation is: The current *implementation* is broken.
Jan 24 2013
Am Thu, 24 Jan 2013 12:51:32 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't;for properties and those who didn't. Seriously, I never found it have pretty clear rules.(b) property adds noise for everybody for the sake of a corner case (functions returning delegates);Partially true, although the real question is whether the additional () are really noise or actually useful. A hardcore C programmer (wants to see every function call) and a ruby developer could probably have a long discussion about that.(c) the property discipline failed to align itself in any way with better code quality.It's hard to verify if code quality changed if the feature isn't properly implemented. Even if it was properly implemented comparing code quality probably isn't easy.
Jan 24 2013
On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/24/13 7:13 AM, Bernard Helyer wrote:No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you). Stop mischaracterizing what really happened: It's well known that you never liked or fully understood the idea of properties in the first place, even by your own admission. So you made a post some number of months back attempting to drum up dissent for properties by stirring up the notion, which just about only you believed, that the choice between property and function is inherently unclear. So to "prove" this you cherry-picked some grey area cases (gee, occasional grey judgement calls when mapping ideas into code, yea, there's something that doesn't happen without property). You succeeded ONLY in proving that there exist *some* cases which may be grey-area judgement calls (again, big surprise, occasional grey-area judgement calls when writing code). But then you - and ONLY you - took this proof that "*some* cases exist" and declared "Look, look, everyone! I proved that *nobody* can agree on property vs function *in general*! QED!" And you continue declaring that non-sequitur to this day.On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't;This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.This is lazy design, plain and simple. You say it's turned into a monster, but property, at its core, is simpler than the heuristics you've demonstrated here. To my mind, property, properly implemented is simple: property functions may be called with no parens or with assignment as the singular argument. Non property functions may not. There. No complications. The only complications come from D's history. And then you want to turn it back? This seems a terrible idea -- the deed is done, pull the trigger. Make property mandatory for property functions.(b) property adds noise for everybody for the sake of a corner case (functions returning delegates);The only reason functions returning delegates have *ever* been an any issue at all is *purely* because of the insistence on optional parens on arbitrary function calls.(c) the property discipline failed to align itself in any way with better code quality.Ok, now *that* argument is just pure unadulterated bullshit. In yes, the general consensus IS that they DO definitely help. Please take your blinders off, and you'll see that. But then there's D, which adds a half-baked and incompletely-implemented "properties" - and did so *reluctantly* I should add. Leaves it in that broken state untouched for a year or two. And now here you are effectively saying "This half-designed/half-implemented feature is causing dissent and not helping people, therefore the problem must be the whole idea of properties and couldn't possibly be due to our broken version of them" (for the record - I *do* find D's current properties helpful, just not as helpful as they would be if they weren't broken).
Jan 24 2013
On 1/24/13 3:45 PM, Nick Sabalausky wrote:On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens! -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On Thursday, January 24, 2013 13:08:08 Adam Wilson wrote:On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:He does have a tendancy to get out of hand in that regard.On 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude,On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andreithe crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!Exactly. That's what _should_ have happened. We wouldn't have all of these optional parens. Unfortunately however, optional parens are so popular for at least some use cases (e.g. UFCS), that I don't think that there's much chance of them going away. - Jonathan M Davis
Jan 24 2013
On Thu, 24 Jan 2013 13:19:49 -0800, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Thursday, January 24, 2013 13:08:08 Adam Wilson wrote:because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory. And to be honest, once the language spec settles down tools like ReSharper/VisualAssist/etc. can take care of the extra parens. I hand type -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:He does have a tendancy to get out of hand in that regard.On 1/24/13 3:45 PM, Nick Sabalausky wrote:thatOn Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examplesWhile I don't approve of Mr. Sabalausky's tone or attitude,sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andreithe crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!Exactly. That's what _should_ have happened. We wouldn't have all of these optional parens. Unfortunately however, optional parens are so popular for at least some use cases (e.g. UFCS), that I don't think that there's much chance of them going away. - Jonathan M Davis
Jan 24 2013
On 01/24/2013 10:24 PM, Adam Wilson wrote:... because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory.It is not a shortcut, it is a formatting option, and using it does not have side effects.And to be honest, once the language spec settles down tools like ReSharper/VisualAssist/etc. can take care of the extra parens.Tools will be configurable to highlight certain constructs anyway.code.It is about reading, not typing.
Jan 24 2013
On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:On 01/24/2013 10:24 PM, Adam Wilson wrote:*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/... because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory.It is not a shortcut, it is a formatting option, and using it does not have side effects.And to be honest, once the language spec settles down tools like ReSharper/VisualAssist/etc. can take care of the extra parens.Tools will be configurable to highlight certain constructs anyway.code.It is about reading, not typing.
Jan 24 2013
On 01/25/2013 12:23 AM, Adam Wilson wrote:... But what happens if t.baz returns a delegate?You mean, a parameterless delegate. How many times does this occur that it supports nuking a entire language feature?Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions.Because the compiler is broken.The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't...It should for properties.Optional Parens Encourage Ambiguity.We could talk about fixing that particular situation, eg, only allow paren-free calls when no parameterless callable is returned, with a very explicit error message. (Like Jesse suggests as well.) However, note that scala does the same we do now: scala> def foo()=()=>2 foo: ()() => Int scala> foo res1: () => Int = <function0> scala> foo() res2: () => Int = <function0> scala> foo()() res3: Int = 2 I do not think this is a recurring discussion topic on the scala newsgroup. I think we might actually be fine.Ambiguity Fosters Bugs.Delegates not being called is noticed quickly.
Jan 24 2013
On 1/24/13 8:01 PM, Timon Gehr wrote:On 01/25/2013 12:23 AM, Adam Wilson wrote:I feel we're getting somewhere! Andrei... But what happens if t.baz returns a delegate?You mean, a parameterless delegate. How many times does this occur that it supports nuking a entire language feature?Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions.Because the compiler is broken.The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't...It should for properties.Optional Parens Encourage Ambiguity.We could talk about fixing that particular situation, eg, only allow paren-free calls when no parameterless callable is returned, with a very explicit error message. (Like Jesse suggests as well.) However, note that scala does the same we do now: scala> def foo()=()=>2 foo: ()() => Int scala> foo res1: () => Int = <function0> scala> foo() res2: () => Int = <function0> scala> foo()() res3: Int = 2 I do not think this is a recurring discussion topic on the scala newsgroup. I think we might actually be fine.Ambiguity Fosters Bugs.Delegates not being called is noticed quickly.
Jan 24 2013
2013/1/25 Adam Wilson <flyboynw gmail.com>On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch> wrote: On 01/24/2013 10:24 PM, Adam Wilson wrote:1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. and removing redundant ()s. Kenji Hara*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs.... because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory.It is not a shortcut, it is a formatting option, and using it does not have side effects. And to be honest, once the language spec settles down toolslike ReSharper/VisualAssist/etc. can take care of the extra parens.Tools will be configurable to highlight certain constructs anyway.code.It is about reading, not typing.
Jan 24 2013
On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com> wrote:2013/1/25 Adam Wilson <flyboynw gmail.com>I can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 15:04:20 -0800, Timon Gehr <timon.gehr gmx.ch> wrote: On 01/24/2013 10:24 PM, Adam Wilson wrote:1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s. Kenji Hara*sigh* ideally yes, it's just a formating option. The problem is that right now, it's NOT. Consider: module main; import std.stdio; struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } int main(string[] argv) { writeln("Hello D-World!"); return 0; Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // is this a function or a property? oops have to go look at the code. } But what happens if t.baz returns a delegate? Because properties, which conceptually have nothing to do with functions, are implemented as functions they have the same optional parens rules as functions. The problem is that they aren't intended to be used as functions so in the case of delegate, you get massive explosions in the compiler. For something that should be straight-forward. If t.baz is a delegate than t.baz() should call the DELEGATE, but it doesn't... Optional Parens Encourage Ambiguity. Ambiguity Fosters Bugs.... because it's syntactically clear. Yes, it might be slightly annoying to have to type the (), but that's how you define a function in every other language. A shortcut with side-effects isn't a short-cut, it's a bug factory.It is not a shortcut, it is a formatting option, and using it does not have side effects. And to be honest, once the language spec settles down toolslike ReSharper/VisualAssist/etc. can take care of the extra parens.Tools will be configurable to highlight certain constructs anyway. I hand type a small fraction of the parens that actually appear in mycode.It is about reading, not typing.
Jan 24 2013
2013/1/25 Adam Wilson <flyboynw gmail.com>On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com> wrote:I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about? Kenji Hara1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s. Kenji HaraI can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
Jan 24 2013
On Thu, 24 Jan 2013 17:27:52 -0800, kenji hara <k.hara.pg gmail.com> wrote:2013/1/25 Adam Wilson <flyboynw gmail.com>Very clever Mr. Hara, I like it a lot! But good luck convincing Walter+Andrei. :-) -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com> wrote:I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about? Kenji Hara1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s. Kenji HaraI can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
Jan 24 2013
On 1/24/13 8:27 PM, kenji hara wrote:I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about? Kenji HaraBrings completeness. But at this point I'm inclined to simplify, never apply "()" deeply is very sensible. If we also find a simple way to implement writing for properties we may be able to eliminate property entirely. Andrei
Jan 24 2013
On Friday, 25 January 2013 at 01:28:05 UTC, kenji hara wrote:I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attribute How about?function seems like an extra complication. Ambiguity between setter and getter for properties when UFCS come into play are not solved. Functional style is impaired as you can't pass regular function around, just function . You'll still find trap in generic code around the behavior of regular functions.
Jan 24 2013
2013/1/25 deadalnix <deadalnix gmail.com>function seems like an extra complication. Ambiguity between setter and getter for properties when UFCS come into play are not solved. Functional style is impaired as you can't pass regular function around, just function . You'll still find trap in generic code around the behavior of regular functions.That's a good point. We need to solve another ambiguity about top-level property function which have a parameter, between top-level property setter and UFCS property getter. module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features. Kenji Hara
Jan 24 2013
On Friday, 25 January 2013 at 05:35:19 UTC, kenji hara wrote:module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features. Kenji Hara"1.foo" must be compile error here. Makes as much sense as int a; void main() { 1.a; } Property must behave exactly like data or it is not a property.
Jan 25 2013
On Friday, 25 January 2013 at 10:56:14 UTC, mist wrote:On Friday, 25 January 2013 at 05:35:19 UTC, kenji hara wrote:I don't see 1.foo the way you see it. I see it like this: property bool is_zero(X value) { return value == 0; } void main() { X value; value.is_zero; } It's just that X happens to be a built-in type, instead of a user-defined type. But I don't see why should that matter.module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features. Kenji Hara"1.foo" must be compile error here. Makes as much sense as int a; void main() { 1.a; } Property must behave exactly like data or it is not a property.
Jan 25 2013
On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:... But I don't see why should that matter.But I don't see why that should matter. ...aced it.
Jan 25 2013
On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:I don't see 1.foo the way you see it. I see it like this: property bool is_zero(X value) { return value == 0; } void main() { X value; value.is_zero; } It's just that X happens to be a built-in type, instead of a user-defined type. But I don't see why should that matter.It is a tempting attempt to save two symbols of typing that completely breaks property semantics. I am objecting against it. With all my passion. Use value.is_zero() for UFCS magic.
Jan 25 2013
On Friday, 25 January 2013 at 14:29:22 UTC, mist wrote:It is a tempting attempt to save two symbols of typing that completely breaks property semantics. I am objecting against it. With all my passion. Use value.is_zero() for UFCS magic.My understanding of the point of UFCS has been that it enables you to add functionality to a type without actually modifying the type. So, let me get this straight... are you saying that the following code snippet breaks property semantics? struct MyType {} property bool is_valid(MyType) { return true; } void main() { MyType mt; mt.is_valid; } Or, are you saying that we shouldn't be able to add properties to built-in types? Or are you saying something else entirely?
Jan 25 2013
Meaning of property for free functions is well-defined. Most rememeber. I see two possible approaches here: 1) ----- property void symbol1(Data); property Data symbol1(); Data symbol2; ... symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 for user symbol2.symbol1; // prohibited, symbol1 is semantically a global variable ----- 2) ----- property void symbol1(Data); property Data symbol1(); Data symbol2; ... symbol1 = symbol2; // prohibited, symbol1 has meaning only within UFCS and imitates Data member. symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), follows general property rules but for compound symbol ----- First one seems more natural to me, but I can live with either approach. Not both. Also please mote that UFCS is meant for enhancing data type functionality with free functions, not implementing every possible feature available to that data type with native syntax.
Jan 25 2013
On 2013-01-25 15:55, mist wrote:Meaning of property for free functions is well-defined. Most likelyfor existing classes. The end result is the same. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 15:02:46 UTC, Jacob Carlborg wrote:On 2013-01-25 15:55, mist wrote:Great, could you give a sample? Does it work on compile time or injects in run-time? Is calling of such methods allowed in usual free form? following materials available in the internet, would be really interesting to learn from their approach.Meaning of property for free functions is well-defined. Most likely rememeber.methods for existing classes. The end result is the same.
Jan 25 2013
On 2013-01-25 16:05, mist wrote:Great, could you give a sample? Does it work on compile time or injects in run-time? Is calling of such methods allowed in usual free form? materials available in the internet, would be really interesting to learn from their approach.The secret is to add "this" in front of the argument type you want to the method to extend: namespace ExtensionMethods { public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } } using ExtensionMethods; string s = "Hello Extension Methods"; int i = s.WordCount(); http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 15:13:21 UTC, Jacob Carlborg wrote:The secret is to add "this" in front of the argument type you want to the method to extend: namespace ExtensionMethods { public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } } using ExtensionMethods; string s = "Hello Extension Methods"; int i = s.WordCount(); http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspxGood. Main questions remain though: is property syntax allowed on extension methods? Is WordCount(s) call allowed?
Jan 25 2013
On 2013-01-25 16:16, mist wrote:Good. Main questions remain though: is property syntax allowed on extension methods? Is WordCount(s) call allowed?I'm not particular familiar with this, perhaps someone else can answer these questions. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 14:55:09 UTC, mist wrote:Meaning of property for free functions is well-defined. Most rememeber. I see two possible approaches here: 1) ----- property void symbol1(Data); property Data symbol1(); Data symbol2; ... symbol1 = symbol2; // allowed, symbol1 behaves same as symbol2 for user symbol2.symbol1; // prohibited, symbol1 is semantically a global variable ----- 2) ----- property void symbol1(Data); property Data symbol1(); Data symbol2; ... symbol1 = symbol2; // prohibited, symbol1 has meaning only within UFCS and imitates Data member. symbol2.symbol1; // Fine, rewritten as symbol1(symbol2), follows general property rules but for compound symbol ----- First one seems more natural to me, but I can live with either approach. Not both. Also please mote that UFCS is meant for enhancing data type functionality with free functions, not implementing every possible feature available to that data type with native syntax.See what is proposed here : http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.org
Jan 25 2013
On Friday, 25 January 2013 at 15:05:11 UTC, deadalnix wrote:See what is proposed here : http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=3#post-uagknsecziepoedcabvr:40forum.dlang.orgLooks somewhat solid to me, with some disagreement on UFCS side :) Will reply with comments to that post.
Jan 25 2013
On Fri, 25 Jan 2013 15:29:21 +0100 "mist" <none none.none> wrote:On Friday, 25 January 2013 at 14:18:43 UTC, TommiT wrote:I think you might have misunderstood it. What he's trying to do is use UFCS to add a property to a type instead of adding a function.I don't see 1.foo the way you see it. I see it like this: property bool is_zero(X value) { return value == 0; } void main() { X value; value.is_zero; } It's just that X happens to be a built-in type, instead of a user-defined type. But I don't see why should that matter.It is a tempting attempt to save two symbols of typing that completely breaks property semantics. I am objecting against it. With all my passion. Use value.is_zero() for UFCS magic.
Jan 25 2013
On Friday, 25 January 2013 at 19:54:29 UTC, Nick Sabalausky wrote:I think you might have misunderstood it. What he's trying to do is use UFCS to add a property to a type instead of adding a function.I got it. What I am questioning is that allowing this in some way is a must. And somewhat changed my mind after that :) There is semantic ambiguity here currently (rules are too lax) that I have described in wiki http://wiki.dlang.org/Property_Discussion_Wrap-up - and I pretty much like proposal there.
Jan 25 2013
On Friday, January 25, 2013 14:35:08 kenji hara wrote:2013/1/25 deadalnix <deadalnix gmail.com>Well, better that then get rid of property. The other big question is what to do with opDispatch, since unless we add the ability to overload on property with opDispatch, then it can't work with both properties and non-property functions. Maybe opPropDispatch or somesuch could be introduced to solve that particular problem. As for the top-level property problem, we could do something like property(set) / property(get) to distinguish. Or if we don't want the extra complication, we can just leave it. As long as you can use it as both a getter and a setter, it works, even if it still allows for weird uses. It would be nice to have a way to disambiguate it however. - Jonathan M Davisfunction seems like an extra complication. Ambiguity between setter and getter for properties when UFCS come into play are not solved. Functional style is impaired as you can't pass regular function around, just function . You'll still find trap in generic code around the behavior of regular functions.That's a good point. We need to solve another ambiguity about top-level property function which have a parameter, between top-level property setter and UFCS property getter. module abc; property int foo(int n); void main() { foo = 1; // top-level property setter 1.foo; // property getter with UFCS } We cannot distinguish the two usages without adding any new features.
Jan 24 2013
On Friday, 25 January 2013 at 05:51:44 UTC, Jonathan M Davis wrote:Well, better that then get rid of property. The other big question is what to do with opDispatch, since unless we add the ability to overload on property with opDispatch, then it can't work with both properties and non-property functions. Maybe opPropDispatch or somesuch could be introduced to solve that particular problem.Can you explain the problem you see with opDispatch ?
Jan 24 2013
On Friday, January 25, 2013 07:14:29 deadalnix wrote:On Friday, 25 January 2013 at 05:51:44 UTC, Jonathan M Davis wrote:If you make opDispatch property, then you can't use it with normal functions, and if you don't make it property, then it can't be used with property functions. And you can't overload on property, so opDispatch is pretty much screwed with regards to properties at this point. It's certainly fixable, but there will need to be a (small) change in the language to do so. - Jonathan M DavisWell, better that then get rid of property. The other big question is what to do with opDispatch, since unless we add the ability to overload on property with opDispatch, then it can't work with both properties and non-property functions. Maybe opPropDispatch or somesuch could be introduced to solve that particular problem.Can you explain the problem you see with opDispatch ?
Jan 24 2013
On Friday, 25 January 2013 at 06:21:59 UTC, Jonathan M Davis wrote:If you make opDispatch property, then you can't use it with normal functions, and if you don't make it property, then it can't be used with property functions. And you can't overload on property, so opDispatch is pretty much screwed with regards to properties at this point. It's certainly fixable, but there will need to be a (small) change in the language to do so.OK, so opDispatch must definitively be transformed ! I have to say I didn't saw that coming. It isn't that big of a deal if we consider we rewrite that way : a.b => a.opDispatch!"b" a.b!T => a.opDispatch!("b", T) No need for opDispatch to actually be a function. According to what is passed as string, opDispatch can resolve itself as a function or a delegate. See example : class Madness { private void function(Madness)[string] fun; property auto opDispatch(string name)() { immutable f = fun[name]; return { return f(this); }; } } A proper inlining mechanism should handle that.
Jan 24 2013
On Friday, 25 January 2013 at 01:28:05 UTC, kenji hara wrote:2013/1/25 Adam Wilson <flyboynw gmail.com>I dunno, but for me the line above is a function pointer that is stored into an integer for later retrieval and use.On Thu, 24 Jan 2013 17:15:09 -0800, kenji hara <k.hara.pg gmail.com> wrote:I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. combination of UFCS and removing redundant ()s. required. Kenji HaraI can completely agree with this change. It is perfectly workable to fix properties without changing optional parens. I just won't use them :-P
Jan 25 2013
2013/1/25 kenji hara <k.hara.pg gmail.com>I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attributeI think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses Kenji Hara
Jan 24 2013
On Friday, 25 January 2013 at 01:38:01 UTC, kenji hara wrote:2013/1/25 kenji hara <k.hara.pg gmail.com>English grammar don't have any functional style enable. It is not possible to return runs itself.I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attributeI think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses Kenji Hara
Jan 24 2013
On 1/24/2013 5:15 PM, kenji hara wrote:1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. removing redundant ()s.Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
On Friday, January 25, 2013 00:19:28 Walter Bright wrote:On 1/24/2013 5:15 PM, kenji hara wrote:Considering that it's always been the plan that property would be enforced such that any use of it would be illegal with parens (it's explicitly among the things tha TDPL says about property), the expectation of pretty much every D programmer is that that's how property functions are to be used, and it shouldn't come as any surprise when that's enforced. As such, I really don't think that it's a big deal if we simply start enforcing that property functions be called without parens. And if you're really concerned about breakage, then we could start with making it a warning rather than an error. But I wager that in almost all cases, any such warning or error would be triggered by a mistake rather than someone intentially using parens with an property function. - Jonathan M Davis1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s.Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
On Friday, 25 January 2013 at 08:19:28 UTC, Walter Bright wrote:On 1/24/2013 5:15 PM, kenji hara wrote:Yes, or maybe we should adopt a sane release process . . .1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. combination of UFCS and removing redundant ()s. required.Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
On Friday, January 25, 2013 00:29:52 Jonathan M Davis wrote:On Friday, January 25, 2013 00:19:28 Walter Bright wrote:In fact, I'd argue that making property enforce that a function be called without parens would be on par with things like starting to enforce that final switch has cases for all of the values in an enum. Yes, it can break code, but it only breaks code because the feature wasn't enforcing what it was supposed to enforce per the spec. And we've made those sorts of changes before. It's really just a bug fix, albeit one that risks having a larger impact than many. Code which follows the spec won't be broken by the change. - Jonathan M DavisOn 1/24/2013 5:15 PM, kenji hara wrote:Considering that it's always been the plan that property would be enforced such that any use of it would be illegal with parens (it's explicitly among the things tha TDPL says about property), the expectation of pretty much every D programmer is that that's how property functions are to be used, and it shouldn't come as any surprise when that's enforced. As such, I really don't think that it's a big deal if we simply start enforcing that property functions be called without parens. And if you're really concerned about breakage, then we could start with making it a warning rather than an error. But I wager that in almost all cases, any such warning or error would be triggered by a mistake rather than someone intentially using parens with an property function.1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s.Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
2013/1/25 Walter Bright <newshound2 digitalmars.com>On 1/24/2013 5:15 PM, kenji hara wrote:Instead, we can simply change the semantic behavior, when -property switch is specified. Because -property switch should have been used for enabling "experimental feature". In phobos, we need to care the semantic change by adding `static if` branches. By the following code we can detect whether the -property switch is really specified or not. enum enforceProperty = !__traits(compiles, { int prop(){ return 1; } int n = prop; }); Kenji Hara1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. UFCS and removing redundant ()s.Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.
Jan 25 2013
On Friday, 25 January 2013 at 08:19:28 UTC, Walter Bright wrote:On 1/24/2013 5:15 PM, kenji hara wrote: Create a new property attribute, say, prop. Imbue it with the new behavior. Leave the old property as it is, and let it cycle through the usual warning, deprecation, removal process.I think the way picked to do the change is, now, of secondary importance. Prioritary is to decide what is the aim of that change. OTOH, I reallyy do not like " prop" (proposal? proposition? property? proponent?), maybe a better name is needed. Tooo bad, I feel like the best word for that, namely " property" was wasted.
Jan 25 2013
On Friday, January 25, 2013 09:54:02 eles wrote:Tooo bad, I feel like the best word for that, namely " property" was wasted.I dispute that we can't just use property since it was its design from the get-go that it would require that there be no parens (it's even discussed in TDPL). It's just that it hasn't been properly enforced. Making it so that it's enforced would be like when we fixed it so that the compiler enforced that final switch statements had cases for all of an enum's values. Code which followed the spec was unaffected, and for any code that _was_ affected, the new enforcement was catching a bug. - Jonathan M Davis
Jan 25 2013
On Friday, January 25, 2013 10:15:09 kenji hara wrote:1. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying () for property function name always applied to its returned value. and removing redundant ()s.I'd say that we should do both. It's ridiculous to accept parens on property functions, since the whole point is that they be used as if they were variables. They're _supposed_ to be illegal (though -property doesn't check for it right now like it's supposed to - it only checks whether parens are used on non-property functions). So, I don't think that there's any question - Jonathan M Davis
Jan 24 2013
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>On Friday, January 25, 2013 10:15:09 kenji hara wrote:Two months ago, I've tried to implement the rule and posted an experimental pull request. https://github.com/D-Programming-Language/dmd/pull/13111. Optional parentheses for normal functions should work shallowly IMO. 2. Optional parentheses for property functions should not work. Applying()for property function name always applied to its returned value.UFCSand removing redundant ()s.I'd say that we should do both. It's ridiculous to accept parens on property functions, since the whole point is that they be used as if they were variables. They're _supposed_ to be illegal (though -property doesn't check for it right now like it's supposed to - it only checks whether parens are used on non-property functions). So, I don't think that there's any question put enough.From that experience, we still need to define some behaviors of cornercases, even if the rule is applied. One of them is getting an address of property function which returns ref. property ref int foo(); auto x = &foo; // x is a function pointer, or an address of returned value? This is the most sensible problem. (a) If typeof(x) should be a function pointer, we need to use a utility function to get int*. ref identity(T)(ref T t) { return t; } int* p1 = &(identity(foo)); // foo is evaluated to ref int in function argument, // and identity gets through the reference. int* p1 = &foo.identity; // with UFCS, parentheses can be removed. This is a real issue. In phobos, the ref-ness of front property is actually checked in std.range.moveFront. (b) If typeof(x) should be a int*, we will lose the way to getting a function pointer of foo. That is more serious than (a). If we adopt this rule, we will *really* get lost the way to distinguish property functions and raw data fields. (Note that: In current typeof(foo) already returns int. So AddressExp is only one way to getting (normal|property) function information by its type.) From the view of meta-programming, I think this makes a serious flaw. Kenji Hara
Jan 24 2013
On 01/25/2013 03:09 AM, kenji hara wrote:... property ref int foo(); auto x = &foo; // x is a function pointer, or an address of returned value?Address of returned value.This is the most sensible problem. (a) If typeof(x) should be a function pointer, we need to use a utility function to get int*. ref identity(T)(ref T t) { return t; } int* p1 = &(identity(foo)); // foo is evaluated to ref int in function argument, // and identity gets through the reference. int* p1 = &foo.identity; // with UFCS, parentheses can be removed. This is a real issue. In phobos, the ref-ness of front property is actually checked in std.range.moveFront.This is a serious issue.(b) If typeof(x) should be a int*, we will lose the way to getting a function pointer of foo. That is more serious than (a). If we adopt this rule, we will *really* get lost the way to distinguish property functions and raw data fields. (Note that: In current typeof(foo) already returns int. So AddressExp is only one way to getting (normal|property) function information by its type.) From the view of meta-programming, I think this makes a serious flaw.We might add the necessary __traits to make up for it.
Jan 24 2013
On Thursday, 24 January 2013 at 21:20:01 UTC, Jonathan M Davis wrote:We wouldn't have all of these problems if we'd justhttp://msdn.microsoft.com/en-us/library/w86s7x04(v=VS.80).aspx "To the user of an object, a property appears to be a field, accessing the property requires exactly the same syntax." Say it with me: properties are DATA FIELDS. Function syntax has NOTHING to do with them! We could change function syntax to require you to draw out some ASCII art of a running cat.... and it shouldn't affect properties one bit. Optional parens is a matter of function syntax. Properties are data fields, so function syntax doesn't matter to them.
Jan 24 2013
On Thu, 24 Jan 2013 13:34:45 -0800, Adam D. Ruppe <destructionator gmail.com> wrote:On Thursday, 24 January 2013 at 21:20:01 UTC, Jonathan M Davis wrote:The problem is that optional parens introduce ambiguity in relation to what is a property versus a function from the compilers prospective. So they are a matter of functional call syntax in that they are non-trivial for the compiler to deduce between the two. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/We wouldn't have all of these problems if we'd justhttp://msdn.microsoft.com/en-us/library/w86s7x04(v=VS.80).aspx "To the user of an object, a property appears to be a field, accessing the property requires exactly the same syntax." Say it with me: properties are DATA FIELDS. Function syntax has NOTHING to do with them! We could change function syntax to require you to draw out some ASCII art of a running cat.... and it shouldn't affect properties one bit. Optional parens is a matter of function syntax. Properties are data fields, so function syntax doesn't matter to them.
Jan 24 2013
On Thursday, 24 January 2013 at 21:41:58 UTC, Adam Wilson wrote:The problem is that optional parens introduce ambiguity in relation to what is a property versus a function from the compilers prospective.No, it doesn't. struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // error, type int has no call method
Jan 24 2013
On Thu, 24 Jan 2013 13:45:44 -0800, Adam D. Ruppe <destructionator gmail.com> wrote:On Thursday, 24 January 2013 at 21:41:58 UTC, Adam Wilson wrote:Right, this conversation is about removing property, which invalidates your argument by turning the data into a function, which is what we want to avoid. Also you might want to run your examples before posting them. t.baz() is NOT an error, which incidentally why the ambiguities I mentioned exist and need to be quashed. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/The problem is that optional parens introduce ambiguity in relation to what is a property versus a function from the compilers prospective.No, it doesn't. struct Thing { int foo() { return 0; } // method int bar; // data field property int baz() { return 0; } // data field } Thing t; t.bar = 10; // this is a data field because it is // declared as "int bar" above, // not because I didn't use parens down here t.foo; // this is a function call because t.foo is a function t.baz; // this is a data field because i declared // " property int" above, not because I left off parens here t.bar(); // error, type int has no call method t.baz(); // error, type int has no call method
Jan 24 2013
On Thursday, 24 January 2013 at 21:53:27 UTC, Adam Wilson wrote:Right, this conversation is about removing property, which invalidates your argument by turning the data into a function, which is what we want to avoid.Yeah, that's why I'm against the OP proposal.Also you might want to run your examples before posting them.I did.... on my modified dmd where property has a less stupid (but still buggy) implementation. It works correctly there!
Jan 24 2013
On Thu, 24 Jan 2013 14:06:47 -0800, Adam D. Ruppe <destructionator gmail.com> wrote:On Thursday, 24 January 2013 at 21:53:27 UTC, Adam Wilson wrote:Hehe, so am I! :-)Right, this conversation is about removing property, which invalidates your argument by turning the data into a function, which is what we want to avoid.Yeah, that's why I'm against the OP proposal.I see. I like it. :-) -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/Also you might want to run your examples before posting them.I did.... on my modified dmd where property has a less stupid (but still buggy) implementation. It works correctly there!
Jan 24 2013
On Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:The problem with property isn't property, it's D's insistence on optional parens.No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function! This is so important: a property is supposed to be indistinguishable from a data member. That's the fundamental definition. It should be fully interchangeable for a plain data member. In other words, as far as the user is concerned, a property *is* a data member, NOT a function! If functions have optional parens, that changes nothing about how you access data members.... and since properties are data members, it changes absolutely nothing about them either. If we required data to be accessed with foo->bar and methods to be called [foo:bar].... a property would be accessed foo->bar. The method syntax is irrelevant. That the property is implemented with a function call should not be known to the user code.
Jan 24 2013
On Thursday, January 24, 2013 22:24:58 Adam D. Ruppe wrote:On Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:D's insistance on optional parens _does_ cause problems with functions that return delegates, but property itself isn't really affected by optional parens save for the visual ambiguity caused by optional parens.The problem with property isn't property, it's D's insistence on optional parens.No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function!This is so important: a property is supposed to be indistinguishable from a data member. That's the fundamental definition. It should be fully interchangeable for a plain data member. In other words, as far as the user is concerned, a property *is* a data member, NOT a function! If functions have optional parens, that changes nothing about how you access data members.... and since properties are data members, it changes absolutely nothing about them either. If we required data to be accessed with foo->bar and methods to be called [foo:bar].... a property would be accessed foo->bar. The method syntax is irrelevant. That the property is implemented with a function call should not be known to the user code.This should probably be emphasized more. A property is an abstraction for a variable and how it's implemented should be irrelevant to the caller. Ideally, it would even be irrelevant whether it's a variable or a property function (though making that the case would require both implementing http://d.puremagic.com/issues/show_bug.cgi?id=8006 and providing a way to mark variables such that they're treated as rvalues rather than lvalues; otherwise, it's still possible to break code when turning a variable into a property function). And we can (and should) implement property in a way that deals with properties properly regardless of what we do with parenless function calls. - Jonathan M Davis
Jan 24 2013
On Thu, 24 Jan 2013 22:52:05 +0100 "Jonathan M Davis" <jmdavisProg gmx.com> wrote:And we can (and should) implement property in a way that deals with properties properly regardless of what we do with parenless function calls.I should clarify that this is my view as well. I may be vocally opposed to optional-parens for function calls, but even I'll admit that *is* a much lesser issue than making sure property stays and is implemented properly.
Jan 24 2013
We can delay the decision about "optional parentheses for normal functions". It can be separated from "strict prohibition of optional parentheses for property functions" Kenji Hara 2013/1/25 Nick Sabalausky <SeeWebsiteToContactMe semitwist.com>On Thu, 24 Jan 2013 22:52:05 +0100 "Jonathan M Davis" <jmdavisProg gmx.com> wrote:And we can (and should) implement property in a way that deals with properties properly regardless of what we do with parenless function calls.I should clarify that this is my view as well. I may be vocally opposed to optional-parens for function calls, but even I'll admit that *is* a much lesser issue than making sure property stays and is implemented properly.
Jan 24 2013
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>On Thursday, January 24, 2013 22:24:58 Adam D. Ruppe wrote:I think that the "optional parentheses" feature for normal functions should always work in _shallowly_. Even if a function returns some callable object, "optional parentheses" should not applied to the return object recursively. That means: void delegate() foo() { ... } void main() { auto x = foo(); // typeof(x) == void delegate() auto y = foo; // typeof(y) == void delegate() } Kenji HaraOn Thursday, 24 January 2013 at 21:09:39 UTC, Adam Wilson wrote:D's insistance on optional parens _does_ cause problems with functions that return delegates, but property itself isn't really affected by optional parens save for the visual ambiguity caused by optional parens.The problem with property isn't property, it's D's insistence on optional parens.No, this isn't a problem; function call syntax has nothing whatsoever to do with property because a property is NOT logically a function!
Jan 24 2013
On Friday, 25 January 2013 at 00:42:09 UTC, kenji hara wrote:I think that the "optional parentheses" feature for normal functions should always work in _shallowly_.I agree. This is the way it makes sense (and the way it is now).
Jan 24 2013
On 1/24/13 7:44 PM, Adam D. Ruppe wrote:On Friday, 25 January 2013 at 00:42:09 UTC, kenji hara wrote:So would Kenji's proposal float your boat? AndreiI think that the "optional parentheses" feature for normal functions should always work in _shallowly_.I agree. This is the way it makes sense (and the way it is now).
Jan 24 2013
On Friday, 25 January 2013 at 02:03:27 UTC, Andrei Alexandrescu wrote:would Kenji's proposal float your boat?Yeah, as described in more detail in this post: http://forum.dlang.org/thread/kdqrnl$13ft$1 digitalmars.com?page=16 There's some details I'd still argue, about address of (i say should be the return value), += etc on property (should become setter(getter() + rhs), unless there is no setter, in which case leave it how it is and let it operate on the return value naturally) .... but I'm willing to compromise if we can get these two points: Callable bar(); bar; // must work, returns the callable callable bar()(); // calls the callable property Callable foo(); foo; // just returns the callable foo(); // must call the *Callable*, not just foo And that's what Kenji is talking about, so yes, it is acceptable. The rest is just gravy. BTW I still say the sanest way to implement this is to rewrite foo into (foo()) ASAP. The parens will follow naturally from that, as will references and most everything else. The only hard part after that is to fix up setters, and perhaps clean existing mess out of dmd. But I'm willing to defer to Walter or Kenji's expertise on actually making it happen.
Jan 24 2013
On 1/24/13 7:41 PM, kenji hara wrote:I think that the "optional parentheses" feature for normal functions should always work in _shallowly_. Even if a function returns some callable object, "optional parentheses" should not applied to the return object recursively. That means: void delegate() foo() { ... } void main() { auto x = foo(); // typeof(x) == void delegate() auto y = foo; // typeof(y) == void delegate() } Kenji HaraInteresting, so that would mean if anyone ever wants to get the delegate AND call it in one shot would need to write: foo()(). I think this proposal has merit. Andrei
Jan 24 2013
On Thursday, January 24, 2013 21:01:33 Andrei Alexandrescu wrote:On 1/24/13 7:41 PM, kenji hara wrote:I believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates. - Jonathan M DavisI think that the "optional parentheses" feature for normal functions should always work in _shallowly_. Even if a function returns some callable object, "optional parentheses" should not applied to the return object recursively. That means: void delegate() foo() { ... } void main() { auto x = foo(); // typeof(x) == void delegate() auto y = foo; // typeof(y) == void delegate() } Kenji HaraInteresting, so that would mean if anyone ever wants to get the delegate AND call it in one shot would need to write: foo()(). I think this proposal has merit.
Jan 24 2013
On 1/24/13 9:11 PM, Jonathan M Davis wrote:I believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates.Well how about we just renounce those for the sake of simplification. Andrei
Jan 24 2013
On Thursday, January 24, 2013 21:24:05 Andrei Alexandrescu wrote:On 1/24/13 9:11 PM, Jonathan M Davis wrote:Without explicit properties you can't switch back and forth between something being a property function and a variable - which is one of the main points of properties in the first place. With explicit properties, it's possible. Also, I think that there's real value from an API perspective to mark what is and isn't intended to be used as a property. - Jonathan M DavisI believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates.Well how about we just renounce those for the sake of simplification.
Jan 24 2013
On Friday, January 25, 2013 03:38:20 Jonathan M Davis wrote:On Thursday, January 24, 2013 21:24:05 Andrei Alexandrescu wrote:And actually, something far more important than any of those reasons is the issue of setters. We've focused most of this discussion on optional parens and the situation with getter properties, but setter properties and their issues are also important. Would you want code like this to compile? range.popFront = 17; container.linearRemove = range; path.baseName = ".xyz"; str.icmp = "hello"; enforce(a == b) = "msg"; arr.sameHead = arr2; With property, we can restrict the functions which can be used with the setter syntax to functions where that makes sense. Without it, all kinds of ridiculous code like the code above would be allowed. Allowing optional parens is one thing, but conflating that with properties is something else entirely. Property functions are not just functions which are called without parens, and we shouldn't act like they are. - Jonathan M DavisOn 1/24/13 9:11 PM, Jonathan M Davis wrote:Without explicit properties you can't switch back and forth between something being a property function and a variable - which is one of the main points of properties in the first place. With explicit properties, it's possible. Also, I think that there's real value from an API perspective to mark what is and isn't intended to be used as a property.I believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates.Well how about we just renounce those for the sake of simplification.
Jan 24 2013
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>And actually, something far more important than any of those reasons is the issue of setters. We've focused most of this discussion on optional parens and the situation with getter properties, but setter properties and their issues are also important. Would you want code like this to compile? range.popFront = 17; container.linearRemove = range; path.baseName = ".xyz"; str.icmp = "hello"; enforce(a == b) = "msg"; arr.sameHead = arr2; With property, we can restrict the functions which can be used with the setter syntax to functions where that makes sense. Without it, all kinds of ridiculous code like the code above would be allowed. Allowing optional parens is one thing, but conflating that with properties is something else entirely. Property functions are not just functions which are called without parens, and we shouldn't act like they are.1a. Optional parentheses for normal functions is just allowed for thegetter usage.int foo(); foo(); // ok void bar(int); bar(1); // okIf based on that, such situations which you are worried will not occur. Kenji Hara
Jan 24 2013
On Friday, 25 January 2013 at 02:24:06 UTC, Andrei Alexandrescu wrote:On 1/24/13 9:11 PM, Jonathan M Davis wrote:I don't understand. We want to drop feature that work in other languages and bring benefit, but it is actually impossible to drop a feature that bring many ambiguities for a small syntactic sugar ?I believe that that's what we have now. The problem is when you want a property which returns a delegate. And for that, we need property. Getting rid of property makes it a problem, whereas with property, it can work - as can property functions which return delegates.Well how about we just renounce those for the sake of simplification.
Jan 24 2013
On 2013-01-25 03:11, Jonathan M Davis wrote:On Thursday, January 24, 2013 21:01:33 Andrei Alexandrescu wrote:Yes, that's the way it's always been since the D1 days. -- /Jacob CarlborgInteresting, so that would mean if anyone ever wants to get the delegate AND call it in one shot would need to write: foo()(). I think this proposal has merit.I believe that that's what we have now.
Jan 25 2013
On 1/24/13 4:08 PM, Adam Wilson wrote:On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiOn 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/24/13 4:08 PM, Adam Wilson wrote:Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiOn 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On 1/24/13 4:56 PM, Adam Wilson wrote:I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. AndreiSimplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiThen property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
Jan 24 2013
On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu wrote:Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued.An enum or a literal can't be passed by reference or otherwise have the address taken either, but we don't argue about if they're data or not, and don't change barely related parts of the language over them. void foo(ref int a) {} int b; foo(b); // ok foo(10); // nope test.d(6): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(6): Error: constant 10 is not an lvalue No big deal. Similarly: enum c = 20; foo(c); test.d(12): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(12): Error: constant 20 is not an lvalue Note: the error message betrays some truth about enum's implementation.... but who cares. And finally: property int bar() { return 0; } foo(bar); test.d(9): Error: function test.foo (ref int a) is not callable using argument types (int) test.d(9): Error: bar() is not an lvalue Like the enum, we see a hint in the error message that the compiler is doing a little magic... but who cares.
Jan 24 2013
On Thursday, January 24, 2013 23:15:38 Adam D. Ruppe wrote:On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu wrote:[snip] However, I do think that would be able to mark variables such that they're treated as rvalues such that swapping a variable out with a property function dosen't break code (at least if http://d.puremagic.com/issues/show_bug.cgi?id=8006 gets implemented). - Jonathan M DavisProperties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued.An enum or a literal can't be passed by reference or otherwise have the address taken either, but we don't argue about if they're data or not, and don't change barely related parts of the language over them.
Jan 24 2013
On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:However, I do think that would be able to mark variables such that they're treated as rvalues such that swapping a variable out with a property function dosen't break codeagreed
Jan 24 2013
25-Jan-2013 02:32, Adam D. Ruppe пишет:On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:IMHO this is a critical part of what a property should do - transparently swapping fields with some functional accessors. -- Dmitry OlshanskyHowever, I do think that would be able to mark variables such that they're treated as rvalues such that swapping a variable out with a property function dosen't break code
Jan 25 2013
On Friday, January 25, 2013 22:09:18 Dmitry Olshansky wrote:25-Jan-2013 02:32, Adam D. Ruppe пишет:And for that, we need to keep property. It's impossible without explicit properties (though there are obviously some improvements that we have to make in order to make it work properly with property). - Jonathan M DavisOn Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:IMHO this is a critical part of what a property should do - transparently swapping fields with some functional accessors.However, I do think that would be able to mark variables such that they're treated as rvalues such that swapping a variable out with a property function dosen't break code
Jan 25 2013
On Thu, 24 Jan 2013 14:04:02 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/24/13 4:56 PM, Adam Wilson wrote:... wat? I fail to see what byref has to do with this. It shouldn't matter what the data is to the compiler as both are built on top of functions, the compiler just enforces different calling syntax for each. If this is a problem for properties then it is a problem for functions to... Because from a compiler POV Data.Property.FieldOfReference; is no different than Data.Function().FieldOfReference; But from a syntax standpoint the difference important because Data.Property(InRef, Count).FieldOfReference; is utterly nonsensical where Data.Function(InRef, Count).FieldOfReference; is perfectly legitimate.I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued.Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiThen property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. Andrei-- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
On Thursday, 24 January 2013 at 22:04:02 UTC, Andrei Alexandrescu wrote: [..]There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. AndreiYeah, back in the day it was a relief to no longer have to decide if I needed to write a function or if I needed to write a procedure. With D, it's been a relief to no longer have to use empty () everywhere. I think we've become stuck in a way of thinking that is creating a lot more complexity than is actually required. For example, I can change my perception of what a variable is and instead view it to be specialized form of function. It has a default implementation and implied storage, which is returned by ref. The compiler can optimize away the need to a real function call. If you take on a view like that, then it may be possible to simplify the language by merging specialized types with alternate syntax into one generalized type with identical syntax. You'll also be forced to implement things in a more consistent and unambiguous way as you proceed along. For example, there has to be different methods for getting the address of the data vs the address of the implementation, and the same solution can work for all types provided that they are treated in the same way. --rt
Jan 24 2013
I can imagine a situation that we might not want to treat property functions as DATAs simply. If you have a struct which have some property functions as members, and you'd want to serialize it: struct S { int value_; property int value() { return value_; } } At least, the serialization library should recognize the S.value is a _property function_, not a int DATA. In most case, property functions should be treated as a simple DATA field. but in a few case, it shouldn't. I have thought AddressExpression &func is one of the places. Related bugzilla issue I posted: http://d.puremagic.com/issues/show_bug.cgi?id=9062 Kenji Hara 2013/1/25 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>On 1/24/13 4:56 PM, Adam Wilson wrote:Simplicity is clearly good, but there's something to be said aboutI'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. Andreithose warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiThen property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
Jan 24 2013
On Friday, 25 January 2013 at 00:55:54 UTC, kenji hara wrote:I can imagine a situation that we might not want to treat property functions as DATAs simply. If you have a struct which have some property functions as members, and you'd want to serialize it: struct S { int value_; property int value() { return value_; } } At least, the serialization library should recognize the S.value is a _property function_, not a int DATA. In most case, property functions should be treated as a simple DATA field. but in a few case, it shouldn't. I have thought AddressExpression &func is one of the places. Related bugzilla issue I posted: http://d.puremagic.com/issues/show_bug.cgi?id=9062Indeed ! property should be different as far as reflection is involved. For usage, it shouldn't make any difference.
Jan 24 2013
On 2013-01-25 01:55, kenji hara wrote:I can imagine a situation that we might not want to treat property functions as DATAs simply. If you have a struct which have some property functions as members, and you'd want to serialize it: struct S { int value_; property int value() { return value_; } } At least, the serialization library should recognize the S.value is a _property function_, not a int DATA.A serialization library would only recognize "value_" since it's an instance variable. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 11:00:34 UTC, Jacob Carlborg wrote:On 2013-01-25 01:55, kenji hara wrote:getFields/getProperties/getMethods and you are done. It don't sounds that much of a problem to me.I can imagine a situation that we might not want to treat property functions as DATAs simply. If you have a struct which have some property functions as members, and you'd want to serialize it: struct S { int value_; property int value() { return value_; } } At least, the serialization library should recognize the S.value is a _property function_, not a int DATA.A serialization library would only recognize "value_" since it's an instance variable.
Jan 25 2013
On 24.1.2013 23:04, Andrei Alexandrescu wrote:On 1/24/13 4:56 PM, Adam Wilson wrote:Maybe this will clarify what is meant by "properties are data": // http://dpaste.dzfl.pl/822aab11 auto foo () { return { return 0; }; } property auto bar () { return { return 0; }; } void main () { auto localFoo = foo; assert(!is(typeof(localFoo) == typeof(foo))); auto localBar = bar; assert(is(typeof(localBar) == typeof(bar))); } function: auto localFoo = foo; // call foo and store the result typeof(localFoo) // typeof(data returned by foo) - function pointer typeof(foo) // typeof(function foo) - function data: auto localBar = bar; // get data represented by bar typeof(localBar) // typeof(data represented by bar) - function pointer typeof(bar) // typeof(data represented by bar) - function pointer Data represented by bar can be some value, or a function call that returns a value. As a user of that property I don't care. And I don't want my code to break if that property changes from a function pointer to a function that returns a function pointer. Hence typeof(foo) is a function, and typeof(bar) is a type of that property (type that is returned by a calling bar). I would like to emphasize that property is not a syntactic, but rather a semantic issue.I'm not all that convinced, and it's easy to get wedged into a black vs white position that neglects many subtleties. Properties are DATA, well except when you need to pass fields by reference etc. at which point the syntactic glue comes unglued. There's been a lot of strong positions years ago about functions vs. procedures, statements vs. expressions, or even (the glorious 60s!) in-language I/O primitives vs. I/O as library facilities. Successful languages managed to obviate such dichotomies. AndreiSimplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiThen property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
Jan 25 2013
On 01/24/2013 10:56 PM, Adam Wilson wrote:On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. RobertOn 1/24/13 4:08 PM, Adam Wilson wrote:Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiOn 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as D's. is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 14:15:45 -0800, Robert Schadek <realburner gmx.de> wrote:On 01/24/2013 10:56 PM, Adam Wilson wrote:Well, from a syntax standpoint it's legitimate, and D's dynamic arrays are using it is that D's GC is absurdly naive. When this seemingly benign action causes your program to freeze for non-trivial fractions of a second for the millionth time, it can be quite despair inducing... -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. RobertOn 1/24/13 4:08 PM, Adam Wilson wrote:Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiOn 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as D's. is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 24 2013
On 01/24/2013 11:32 PM, Adam Wilson wrote:On Thu, 24 Jan 2013 14:15:45 -0800, Robert Schadek <realburner gmx.de> wrote:Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it feels strange that assigning a variable resizes a array. Something like a.resize(10) would make me feel better.On 01/24/2013 10:56 PM, Adam Wilson wrote:Well, from a syntax standpoint it's legitimate, and D's dynamic arrays problem with using it is that D's GC is absurdly naive. When this seemingly benign action causes your program to freeze for non-trivial fractions of a second for the millionth time, it can be quite despair inducing...On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:At while you're at it, just get ride of: int[] a. a.length = 10; That this grows the array stills creeps me out. RobertOn 1/24/13 4:08 PM, Adam Wilson wrote:Then property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it. AndreiOn 1/24/13 3:45 PM, Nick Sabalausky wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind. Andrei
Jan 25 2013
On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner Schadek wrote:... Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it feels strange that assigning a variable resizes a array. Something like a.resize(10) would make me feel better.Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
Jan 25 2013
On Friday, 25 January 2013 at 11:01:31 UTC, mist wrote:On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner Schadek wrote:I can view *reading* size as a property, but I don't think the setter itself should be a property, since it actually *does* something. Heck, it can throw an exception (!) However, I really think we are way past the point we can change array's interface. I'd just leave it be.... Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it feels strange that assigning a variable resizes a array. Something like a.resize(10) would make me feel better.Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
Jan 25 2013
On Friday, January 25, 2013 12:24:56 monarch_dodra wrote:On Friday, 25 January 2013 at 11:01:31 UTC, mist wrote:So? Of course, setters can throw exceptions. Why wouldn't they be able to? For instance, if you try and set the hour on a TimeOfDay to 25, it's going to throw a DateTimeException. I could see an argument that the operations that length does when set are expensive enough that it shouldn't be a setter property, but setters are not necessarily going to be as simple as setting a variable, and throwing exceptions from them is normal, depending on what they need to do. I could see generally restricting them to operations which are on properties say something along those lines), but you make it sound as if all a setter property should ever do is simply set a variable, and if that were the case, you might as well just make it a public variable.On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner Schadek wrote:I can view *reading* size as a property, but I don't think the setter itself should be a property, since it actually *does* something. Heck, it can throw an exception (!)... Yes, the syntax is legit. It's the semantic that "scares" me. IMHO it feels strange that assigning a variable resizes a array. Something like a.resize(10) would make me feel better.Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.However, I really think we are way past the point we can change array's interface. I'd just leave it be.It's far too late at this point. I don't know if it was a good design choice or not (and I rarely use it myself), but it's not going to change. - Jonathan M Davis
Jan 25 2013
On Thu, 24 Jan 2013 13:08:08 -0800 "Adam Wilson" <flyboynw gmail.com> wrote:On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:And I simply pointed out how they are incorrect.On 1/24/13 3:45 PM, Nick Sabalausky wrote:On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you).I simply mentioned three reasons that came to mind.While I don't approve of Mr. Sabalausky's tone or attitude,Sorry about that. I'm just frustrated at fighting another uphill D battle against those who have far, far more pull than I do, and are every bit as difficult to sway as I am ;). It's nothing personal against Andrei or Walter or anyone else.
Jan 24 2013
On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:Sorry about that. I'm just frustrated at fighting another uphill D battle against those who have far, far more pull than I do, and are every bit as difficult to sway as I am ;).I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it. But I feel like we're finding common ground this time, where we weren't able to the last several times.
Jan 24 2013
On Fri, 25 Jan 2013 02:57:22 +0100 "Adam D. Ruppe" <destructionator gmail.com> wrote:On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:Getting screamed at and just taking it, without ever giving me crap back about it, is one of the top killer features of electronics technology. It's like a squeezy stress ball, except it's always handy when you need it...Probably because it's usually also the cause, but hey.Sorry about that. I'm just frustrated at fighting another uphill D battle against those who have far, far more pull than I do, and are every bit as difficult to sway as I am ;).I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it.But I feel like we're finding common ground this time, where we weren't able to the last several times.Maybe because we're *all* finally tired of arguing about it ;)
Jan 24 2013
On Fri, 25 Jan 2013 02:57:22 +0100 "Adam D. Ruppe" <destructionator gmail.com> wrote:On Friday, 25 January 2013 at 01:54:03 UTC, Nick Sabalausky wrote:What really got me upset about it was that here we have one of my favorite modern language features, properties, and then all of a sudden outright remove it from the language entirely, instead of enacting, or at least promising to *eventually* enact, the long overdue fixes I've been anxiously awaiting.Sorry about that. I'm just frustrated at fighting another uphill D battle against those who have far, far more pull than I do, and are every bit as difficult to sway as I am ;).I literally screamed at my computer screen a couple times in this thread. This is an argument we've been having for years and I've gotta say, I'm kinda fed up with it.
Jan 25 2013
On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:What really got me upset about it was that here we have one of my favorite modern language features, properties, and then all trying to gut it if not outright remove it from the language entirelyAmen.
Jan 25 2013
On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:What really got me upset about it was that here we have one of my favorite modern language features, properties, and then all of a sudden if not outright remove it from the language entirely, instead of enacting, or at least promising to *eventually* enact, the long overdue fixes I've been anxiously awaiting.If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them. --rt
Jan 25 2013
On 1/25/13 3:18 PM, Rob T wrote:On Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse. AndreiWhat really got me upset about it was that here we have one of my favorite modern language features, properties, and then all of a sudden outright remove it from the language entirely, instead of enacting, or at least promising to *eventually* enact, the long overdue fixes I've been anxiously awaiting.If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them.
Jan 25 2013
On Friday, 25 January 2013 at 21:20:33 UTC, Andrei Alexandrescu wrote:On 1/25/13 3:18 PM, Rob T wrote:OK, understood. I started a discussion in wiki showing how property-like behaviour without full variable emulation can work unambiguously for a few of the edge cases, such as reference returns and taking the addresses, eg, &prop. http://wiki.dlang.org/Talk:Property_Discussion_Wrap-up#ref_returns_and_taking_the_address If we try and fully emulate variables, a ton of complexity starts to creep in. If we do not fully emulate variables, then it significantly weakens the arguments in favor of using property as a means to emulate variable. --rtOn Friday, 25 January 2013 at 20:10:01 UTC, Nick Sabalausky wrote:That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse. AndreiWhat really got me upset about it was that here we have one of my favorite modern language features, properties, and then all of a sudden it if not outright remove it from the language entirely, instead of enacting, or at least promising to *eventually* enact, the long overdue fixes I've been anxiously awaiting.If I correctly understand Walters proposal and Andrei's view point, neither are proposing to fully axe property-like behavior. I stand to be corrected, but they both seem to think that enforcement through property is not required, and that's the main point being put on the chopping block. Walter and Andrei may want to clarify since I cannot speak for them.
Jan 25 2013
On 2013-01-25 22:20, Andrei Alexandrescu wrote:That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name. -- /Jacob Carlborg
Jan 26 2013
On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.How would you declare a template property? The getter would be ambiguous with a regular function declaration, wouldn't it?
Jan 26 2013
On 2013-01-26 16:06, Nicolas Sicard wrote:How would you declare a template property? The getter would be ambiguous with a regular function declaration, wouldn't it?Right... didn't think of that. -- /Jacob Carlborg
Jan 26 2013
On 1/26/13 8:21 AM, Jacob Carlborg wrote:On 2013-01-25 22:20, Andrei Alexandrescu wrote:This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument). AndreiThat's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
Jan 26 2013
On Saturday, 26 January 2013 at 16:29:16 UTC, Andrei Alexandrescu wrote:On 1/26/13 8:21 AM, Jacob Carlborg wrote:I have to say it will get my vote if a way if found to make this UFCS compliant.On 2013-01-25 22:20, Andrei Alexandrescu wrote:This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
Jan 26 2013
On 2013-01-26 17:29, Andrei Alexandrescu wrote:This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).There's two problems with the getter syntax. 1. How to distinguish a template property from a regular function 2. How to distinguish a property without an implementation from a variable declaration -- /Jacob Carlborg
Jan 26 2013
On Sat, 26 Jan 2013 16:29:16 -0000, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/26/13 8:21 AM, Jacob Carlborg wrote:int foo(this Person p) {} void foo= (this Person p, int value) {} R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On 2013-01-25 22:20, Andrei Alexandrescu wrote:This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
Jan 28 2013
On Mon, 28 Jan 2013 05:26:43 -0800, Regan Heath <regan netmail.co.nz> wrote:On Sat, 26 Jan 2013 16:29:16 -0000, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Extension Method. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On 1/26/13 8:21 AM, Jacob Carlborg wrote:int foo(this Person p) {} void foo= (this Person p, int value) {} ROn 2013-01-25 22:20, Andrei Alexandrescu wrote:This is interesting. I wonder how to make it work for UFCS functions (which _do_ have one argument).That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.
Jan 28 2013
On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. confusion between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
Jan 26 2013
On Sat, 26 Jan 2013 11:10:20 -0800, Maxim Fomin <maxim maxim-fomin.ru> wrote:On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:for the compiler to determine whether or not it is a property. class A { private int i; public int foo { get { return i; } set { i = value; } } } -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
Jan 26 2013
On 01/26/13 20:10, Maxim Fomin wrote:On Saturday, 26 January 2013 at 13:21:37 UTC, Jacob Carlborg wrote:Hmm, the current state of them being defined by two separate functions really isn't ideal. But introducing new keywords or magic identifiers just for this does not seem right. class A { private int i; int foo { out { return i; } in(int v) { i = v; } } } or class A { private int i; property foo { int out { return i; } in(int v) { i = v; } } } arturIt's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses. Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.The root of the issue is that in C/C++/D there is tremendous difference between object types and functions types (which are incompatible) and property is like a bridge between them - I think that is why the feature is demanded. However in D a property is essentially a function. Few characteristics that are intrinsic to data types are typeof(prop) which is data type for properties and parenthesis-less access. There is no property as a special entity per se. between data and functions. In D it would look like this: class A { private int i; property int foo // may be without property at all? { get { return i; } set { i = value; } } } In this solution property is not defined by naming of two separate functions and is independent of any function in general.
Jan 26 2013
On Saturday, 26 January 2013 at 21:48:54 UTC, Artur Skawina wrote: [..]Hmm, the current state of them being defined by two separate functions really isn't ideal. But introducing new keywords or magic identifiers just for this does not seem right. class A { private int i; int foo { out { return i; } in(int v) { i = v; } } } or class A { private int i; property foo { int out { return i; } in(int v) { i = v; } } } arturIn a more pefect world, we'd redefine what a variable and function is, merging the two together as one, let the compiler optimize things appropriately, and make the language issues far more consistent and simple. For example, typeof(x) is way too simplistic to be of use when you have objects that have more than on type. For example, a property has a setter, getter, and storage type, so what should typeof(prop) return? It can only tell you one thing out of at least 3 things, so it's insufficient. Great for C, useless for D. We're basically finding ourselves in the same position C++ has found itself in, where the old concepts are no longer suitable for a modern language, but there's no practical way to resolve the situation without redesigning the whole language into a new one. D tried to make a better C++, and it has done a good job of that up to a point, but since it has made use of many of the old paradigms as its base, it can only do so much. One solution is to not bother trying to add on any extra complexity that does not fit in. --rt
Jan 26 2013
On Sat, Jan 26, 2013 at 2:24 PM, Rob T <alanb ucora.com> wrote:We're basically finding ourselves in the same position C++ has found itself in, where the old concepts are no longer suitable for a modern language, but there's no practical way to resolve the situation without redesigning the whole language into a new one. D tried to make a better C++, and it has done a good job of that up to a point, but since it has made use of many of the old paradigms as its base, it can only do so much.That is what I have been noticing as well, unfortunately. As a long time lurker, I like many of the concepts that D introduces, but the many little quirks here and there add up and probably make adoption by a large community much less likely. It would be great if we had more programming languages competing to change the systems programming landscape. The popular systems languages we have been stuck with (namely C and C++) are a mess, and the "replacements" I see announced every once in a while never seem to become bigger than side projects. Currently, the only other potential option I see is Rust. Why not take it all the way? Start with a proper release plan, be willing to break backward compatibility (maybe even by changing the name of the language -- perception matters), take into account all what was learned from the past 10+ years of D's history, potentially try to get corporate backing, and maybe we will have something that is practically viable to push aside C and C++. Then again, maybe I dream too much... -- Ziad
Jan 26 2013
We can almost implement properties as a regular struct struct prop { int _val; ref prop opAssign( int a_val ) { writeln("assignment = ", a_val ); _val = a_val; return this; } int opCall() { writeln("opcall = ", _val ); return _val; } // other op overloads, like ++, --, etc } If we change a few things it may work. Instead of struct it could be named prop eg prop P { ... } opCall needs to be changed so there's no need to specify the (). No dounbt other changes will be needed too to make it more convenient to use and less error prone. The advantage is that with a "property as a struct" implementation, you can wrap up a lot more than just a setter and getter around only one variable, eg internally there could be several vars or even none at all depending on the needs. --rt
Jan 26 2013
On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:We can almost implement properties as a regular struct[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T -- Gone Chopin. Bach in a minuet.
Jan 26 2013
On Sunday, 27 January 2013 at 01:11:05 UTC, H. S. Teoh wrote:On Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:Ah cool! You don't really need property however if we adopt the optional () unless that's to be enforced. The really nice thing about this, is we can return the struct as a ref, and it still works, and also take the address of the struct and it continues to work. Even better I can add more member functions to it and expand on what it can do. The "property as a function" approach is far more limiting and has issues, such as ref returns and taking the address. Anyone know what's missing or what won't work with this approach? --rtWe can almost implement properties as a regular struct[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T
Jan 26 2013
On 01/27/13 03:48, Rob T wrote:On Sunday, 27 January 2013 at 01:11:05 UTC, H. S. Teoh wrote:auto w = Widget(); w.width = 3; w.height = 14; auto a = w.area; Consider an implementation of Widget where some/all of these fields are properties. Also, does adding a "virtual" area property (ie one calculated on demand from the others) influence the layout of the object? Should it? IOW, there are many problems with such a solution, some of which can be worked around, others fixed with relatively small language changes (legalizing zero-sized objects, making a static-outer implementation cleanly doable etc). But would there really be enough gain to justify making properties that much more complicated? The present approach is a reasonable compromise, it just needs proper call handling. Consider the case, that is some times brought up here, where you use a library which at some point is changed and some object fields are replaced by properties. You recompile your code with that newer version. What keeps working? What breaks? Which breakages can be avoided? Which ones would you really want to examine and handle manually? Any field->property change breaks the ABI, but this can only be avoided by preemptively using accessors. That doesn't affect property as such, except that having some kind of syntax sugar would make creating the required forwarders easier. Handling property evaluation correctly not only makes sense, it's necessary to make them work correctly. But further "improvements" bring few extra benefits, while complicating the language. Parens-less function calls are a much bigger problem; I can't see much gain from "cleaning up" the property design. While killing property /is/ an option, it's not a good one either, especially if ()-enforcement on all calls doesn't happen before such a change. arturOn Sun, Jan 27, 2013 at 01:15:29AM +0100, Rob T wrote:Ah cool! You don't really need property however if we adopt the optional () unless that's to be enforced. The really nice thing about this, is we can return the struct as a ref, and it still works, and also take the address of the struct and it continues to work. Even better I can add more member functions to it and expand on what it can do. The "property as a function" approach is far more limiting and has issues, such as ref returns and taking the address. Anyone know what's missing or what won't work with this approach?We can almost implement properties as a regular struct[...] You do it like this: import std.stdio; struct IntProp { int __impl; property /* <-- ah, the irony! */ int value() { return __impl + 123; } alias value this; // watch this magic void opAssign(int val) { __impl = val - 123; } } struct S { IntProp prop; } void main() { S s; writeln(s.prop); s.prop = 321; writeln(s.prop); } T
Jan 27 2013
It would be cool if we could declare variables with anonymous types; struct { opAssign() {} } foo;
Jan 26 2013
On Sunday, 27 January 2013 at 02:54:55 UTC, Adam D. Ruppe wrote:It would be cool if we could declare variables with anonymous types; struct { opAssign() {} } foo;This would be much easier to understand: alias foo struct { opAssign() {} }; Is "singleton structures", a.k.a. properties, a good name for these?
Jan 26 2013
On Sunday, 27 January 2013 at 05:32:25 UTC, Zach the Mystic wrote:On Sunday, 27 January 2013 at 02:54:55 UTC, Adam D. Ruppe wrote:Actually, I don't even think you need alias: foo struct { opAssign() {} }It would be cool if we could declare variables with anonymous types; struct { opAssign() {} } foo;This would be much easier to understand: alias foo struct { opAssign() {} }; Is "singleton structures", a.k.a. properties, a good name for these?
Jan 26 2013
On Sun, Jan 27, 2013 at 03:54:54AM +0100, Adam D. Ruppe wrote:It would be cool if we could declare variables with anonymous types; struct { opAssign() {} } foo;I was thinking we could just use a template to alleviate much of the boilerplate of creating a property using a struct. For example, something like: struct Property(T, alias setter, alias getter) { property T get() { return nullaryFunc!setter(); } alias get this; void opAssign(T val) { return unaryFunc!setter(val); } // ... add other standard stuff like opAssignOp, etc. } Then you could use it like this: struct S { int x, y; Property!(int, ()=>x+y, (int z) { y=z-x; }) derivedProp; } The syntax could do with some improvement, though. Maybe an alias: struct S { alias Property!(int, ()=>x+y, (int z) { y=z-x; }) DerivedProp; int x, y; DerivedProp derivedProp; } S s; s.derivedProp = 123; auto ptr = &s.derivedProp; writeln(*ptr); // etc. T -- Arise, you prisoners of Windows / Arise, you slaves of Redmond, Wash, / The day and hour soon are coming / When all the IT folks say "Gosh!" / It isn't from a clever lawsuit / That Windowsland will finally fall, / But thousands writing open source code / Like mice who nibble through a wall. -- The Linux-nationale by Greg Baker
Jan 26 2013
On 2013-01-26 22:48, Artur Skawina wrote:Hmm, the current state of them being defined by two separate functions really isn't ideal. But introducing new keywords or magic identifiers just for this does not seem right. class A { private int i; int foo { out { return i; } in(int v) { i = v; } } } or class A { private int i; property foo { int out { return i; } in(int v) { i = v; } } }That might conflict with contracts, which also uses "in" and "out". -- /Jacob Carlborg
Jan 27 2013
On 01/27/13 13:02, Jacob Carlborg wrote:On 2013-01-26 22:48, Artur Skawina wrote:It overloads the keywords, but afaict should be unambiguous and is not worse than the other meanings of 'in' (operator, modifier). But I haven't really used contracts w/ D (the basic features need to work right first, before worrying about extras like that); somebody who actually uses them would be in a better position to determine if overloading 'in' and 'out' further would be too confusing. I mentioned this as a possibility, but am not actually convinced that it's a good idea yet. Things like mixin in getters and setters via separate templates would be impaired - this may be unusual, but doesn't meet the "insane" criteria, so shouldn't be disallowed. Which means several property blocks would have to be allowed and effectively merged together. arturHmm, the current state of them being defined by two separate functions really isn't ideal. But introducing new keywords or magic identifiers just for this does not seem right. class A { private int i; int foo { out { return i; } in(int v) { i = v; } } } or class A { private int i; property foo { int out { return i; } in(int v) { i = v; } } }That might conflict with contracts, which also uses "in" and "out".
Jan 27 2013
On 2013-01-27 13:52, Artur Skawina wrote:It overloads the keywords, but afaict should be unambiguous and is not worse than the other meanings of 'in' (operator, modifier). But I haven't really used contracts w/ D (the basic features need to work right first, before worrying about extras like that); somebody who actually uses them would be in a better position to determine if overloading 'in' and 'out' further would be too confusing.I'm not talking about confusing. I'm thinking if it's ambiguous or not and how to attach contracts to a property with this syntax. -- /Jacob Carlborg
Jan 27 2013
On 01/27/2013 02:27 PM, Jacob Carlborg wrote:On 2013-01-27 13:52, Artur Skawina wrote:class A{ private int i; int foo{ out out(result){assert(result<=0);}body{return i; } in(int v)in{assert(v<=0);}out{assert(foo<=0);}body{ i = v; } } }It overloads the keywords, but afaict should be unambiguous and is not worse than the other meanings of 'in' (operator, modifier). But I haven't really used contracts w/ D (the basic features need to work right first, before worrying about extras like that); somebody who actually uses them would be in a better position to determine if overloading 'in' and 'out' further would be too confusing.I'm not talking about confusing. I'm thinking if it's ambiguous or not and how to attach contracts to a property with this syntax.
Jan 27 2013
I think that "property as contract for accessing to variable" is good point. Maybe we have lack proper terminology, but idea is good. Also it is can be pointed as "property itself - is static contract to accessing variable".Unified: class A { private int i; int foo { out{assert( value<=0);}body{return i; } in{assert( value<=0);}body{ i = value; } } } value - in getter it's return value; value - in setter it's param value; void type is not allowed. In theory, property always have only one in/out parameter of same type and performs lightweight actions.class A{ private int i; int foo{ out out(result){assert(result<=0);}body{return i; } in(int v)in{assert(v<=0);}out{assert(foo<=0);}body{ i = v; } } }
Jan 27 2013
On 1/26/2013 5:21 AM, Jacob Carlborg wrote:On 2013-01-25 22:20, Andrei Alexandrescu wrote:Problems if you want to declare the getter but not provide an implementation.That's right with the amendment that we're looking for a solution, not pushing one. Even the title of the thread is a question. Clearly properties are good to have. In an ideal world we wouldn't need a keyword for them and we'd have some simple rules for determining property status (especially when it comes to writes). If syntactic help is necessary, so be it. We want to make the language better, not worse.It's always possible to avoid keywords in favor of syntax. Example: Declaring a getter: int foo {} Just as a regular function declaration but without the parentheses.Declaring a setter: void foo= (int value) {} Append an equal sign to the function name.It is rather similar to a variable declaration with initializer: T foo = expression;
Jan 26 2013
On 2013-01-27 02:23, Walter Bright wrote:Problems if you want to declare the getter but not provide an implementation.Yeah, I noticed that. And declaring a tempalte property.It is rather similar to a variable declaration with initializer: T foo = expression;Yeah, you're right. -- /Jacob Carlborg
Jan 27 2013
On 2013-01-24 22:08, Adam Wilson wrote:While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!There are many languages that allow optional parentheses when calling a function. Ruby, CoffeeScript and Groovy to mention a few. -- /Jacob Carlborg
Jan 25 2013
On Friday, 25 January 2013 at 09:38:27 UTC, Jacob Carlborg wrote:On 2013-01-24 22:08, Adam Wilson wrote:From what I see on CofeeScript website, it has a VERY different semantic than D on function.While I don't approve of Mr. Sabalausky's tone or attitude, the crux of his argument is logically sound. The problem with property isn't property, it's D's insistence on optional parens. If paren usage was clearly defined then this would be a non-issue. I would like to point out that I can't think of another systems/general purpose language that has an calling syntax specification as vague and convoluted as is brutally simple. Java's is brutally simple. In C/C++ everything is a function or field, so, brutally simple. Make D's calling syntax simpler, end optional parens!There are many languages that allow optional parentheses when calling a function. Ruby, CoffeeScript and Groovy to mention a few.
Jan 25 2013
On 2013-01-25 10:49, deadalnix wrote:From what I see on CofeeScript website, it has a VERY different semantic than D on function.How do you mean? Well it has the same semantics as JavaScript since it's compiled to JavaScript. -- /Jacob Carlborg
Jan 25 2013
On Thursday, January 24, 2013 15:45:42 Nick Sabalausky wrote:On Thu, 24 Jan 2013 12:51:32 -0500 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I've never understood what's so hard about knowing what should and shouldn't be considered a property. It's generally very clear IMHO, and if clarification pointing out. Really, it comes down primarily to whether a function would make sense as a variable.No. The complications come from the fact that (a) nobody could agree what should be a property and what shouldn't;No, you merely came up with *some* specific cherry-picked examples that sparked *some* debate (with most of the disagreing coming from you). Stop mischaracterizing what really happened: It's well known that you never liked or fully understood the idea of properties in the first place, even by your own admission. So you made a post some number of months back attempting to drum up dissent for properties by stirring up the notion, which just about only you believed, that the choice between property and function is inherently unclear. So to "prove" this you cherry-picked some grey area cases (gee, occasional grey judgement calls when mapping ideas into code, yea, there's something that doesn't happen without property). You succeeded ONLY in proving that there exist *some* cases which may be grey-area judgement calls (again, big surprise, occasional grey-area judgement calls when writing code). But then you - and ONLY you - took this proof that "*some* cases exist" and declared "Look, look, everyone! I proved that *nobody* can agree on property vs function *in general*! QED!" And you continue declaring that non-sequitur to this day.Indeed.(b) property adds noise for everybody for the sake of a corner case (functions returning delegates);The only reason functions returning delegates have *ever* been an any issue at all is *purely* because of the insistence on optional parens on arbitrary function calls.I think that you're being too extreme in your language and tone here, but I have to agree. - Jonathan M Davis(c) the property discipline failed to align itself in any way with better code quality.Ok, now *that* argument is just pure unadulterated bullshit. In yes, the general consensus IS that they DO definitely help. Please take your blinders off, and you'll see that. But then there's D, which adds a half-baked and incompletely-implemented "properties" - and did so *reluctantly* I should add. Leaves it in that broken state untouched for a year or two. And now here you are effectively saying "This half-designed/half-implemented feature is causing dissent and not helping people, therefore the problem must be the whole idea of properties and couldn't possibly be due to our broken version of them" (for the record - I *do* find D's current properties helpful, just not as helpful as they would be if they weren't broken).
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:4. No more property.Looks fine for me. D2 code is better but sometimes so much noisier than D1. There, I said it.
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.Under the proposed rules, which of the lines in the output of the following program will be the same? --- import std.stdio; int globalInt = 42; auto ref g() { return globalInt; }; auto globalG = &g; auto ref f() { return globalG; } void main() { writeln("&globalInt: ", &globalInt); writeln("globalInt: ", globalInt); writeln("&globalG: ", &globalG); writeln("globalG: ", globalG); writeln("---"); writeln("&f: ", &f); writeln("&f(): ", &f()); writeln("&g: ", &g); writeln("&g(): ", &g()); } --- Also, don't forget that property was actually introduced to solve specific syntactic issues, not just because somebody didn't like the laxness of the previous rules. Now, yes, the current implementation in DMD doesn't solve the issues, while introducing new issues by disallowing parameterless function calls altogether. But I think the last larger discussion on the topic some two to three months ago produced a set of property rules that would actually work. I think there is a summary in DIP21. Anyway, I think you should turn your proposal into a DIP, and better sooner than later so that the details on the edge cases, impact in terms of breaking code, … aren't lost in an endless forum discussion. David
Jan 24 2013
Am 24.01.2013 09:34, schrieb Walter Bright:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.I think Adam D. Ruppe has proposed this in the past and, although I don't really like omitting parentheses on ordinary function calls in general (apart from UFCS template functions), it's clear, simple and I think everyone could be happy with it: 1. Normal function calls _may_ omit parentheses, but "a = b" is _not_ interpreted as "a(b)" 2. property functions can _not_ be called with parentheses and "a = b" _is_ interpreted as "a(b)" 3. Calling a normal function always returns its return value1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.This sounds like a recipe for disaster. Thinking about generic code calling functions... it would surely be very surprising to see how f() sometimes does not return ReturnType!f, but something completely different. It would also break all existing code that currently expects f() to simply return its return value. More importantly, adding or removing an opCall or changing the return type of a function would possibly silently change the meaning of code that calls the function. IMO it is also utterly unexpected/counter-intuitive for a seeming function call not to return its return value, but call it and return the result.2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics.I can live with omitted parentheses (*). However, what's really ugly is picking the unintended form in case of a setter (i.e. both, "obj.prop(value)" instead of "obj.prop = value;", or "countElements = obj;" instead of "obj.countElements()"). And in my experience, people /will/ mix the different forms all over the place. So although I know that some people have a different opinion, I still find it a very useful thing to be able to force correct usage up to a certain degree - stylistically and to avoid ambiguities (not only for the compiler, but also for a human reader). Adam's proposal solves this nicely and it's about as simple as it gets. (*) IMO they are kind of ugly semantically if they are omitted for anything else than properties or UFCS-template functions, but you may well call that a matter of taste3. Parens are required for calling delegates or function pointers. 4. No more property.
Jan 24 2013
On 2013-01-24 14:28, Sönke Ludwig wrote:1. Normal function calls _may_ omit parentheses, but "a = b" is _not_ interpreted as "a(b)" 2. property functions can _not_ be called with parentheses and "a = b" _is_ interpreted as "a(b)" 3. Calling a normal function always returns its return value+1 -- /Jacob Carlborg
Jan 24 2013
On Thursday, 24 January 2013 at 13:28:48 UTC, Sönke Ludwig wrote:Am 24.01.2013 09:34, schrieb Walter Bright:This greatly impairs functional style. Just as you demonstrated nicely with return values, this one cause the same problem with arguments (either to template or functions).This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.I think Adam D. Ruppe has proposed this in the past and, although I don't really like omitting parentheses on ordinary function calls in general (apart from UFCS template functions), it's clear, simple and I think everyone could be happy with it: 1. Normal function calls _may_ omit parentheses, but "a = b" is _not_ interpreted as "a(b)" 2. property functions can _not_ be called with parentheses and "a = b" _is_ interpreted as "a(b)" 3. Calling a normal function always returns its return valueGreat explanation on how it mess up return values when using very functional style.1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.This sounds like a recipe for disaster. Thinking about generic code calling functions... it would surely be very surprising to see how f() sometimes does not return ReturnType!f, but something completely different. It would also break all existing code that currently expects f() to simply return its return value. More importantly, adding or removing an opCall or changing the return type of a function would possibly silently change the meaning of code that calls the function. IMO it is also utterly unexpected/counter-intuitive for a seeming function call not to return its return value, but call it and return the result.
Jan 24 2013
On 24 January 2013 08:34, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.As much as I want to agree, I also feel this comes as too little, too late to come to this conclusion now. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jan 24 2013
On 1/24/13 8:38 AM, Iain Buclaw wrote:On 24 January 2013 08:34, Walter Bright <newshound2 digitalmars.com <mailto:newshound2 digitalmars.com>> wrote: This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property. As much as I want to agree, I also feel this comes as too little, too late to come to this conclusion now.Too little is a good thing actually! Andrei
Jan 24 2013
As much as I want to agree, I also feel this comes as too little, too late to come to this conclusion now.+1 And therefor we should take out property ASAP :-)
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.I'm so happy to read this !!!!Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I'm so unhappy to read this :((((((( Ok let me be more constructive. The current state of thing have 2 issues : on is that non properties are conflated with properties, and the other is that setter is conflated with getter. You solution isn't good because it conflate things even more. Here is my proposal : For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway. 2. funName() call the function. Rationale : function as variable or defined in the source now behave the same way (expect the deprecated & behavior). It makes it easier to write generic code, and in general consistency is a plus (easier to learn the language, less dark corner case to consider, easier interaction with other features). 3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable. 4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given. 5. setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument. setter void funName(T t) {} T t; funName = t; // function gets executed. funName(t); // Error, funName must be used in an assign expression. 6. setter can as well be used as UFCS : getter void funName(T t, U u) {} T t; U u; t.funName = u; // function gets executed. t.funName(u); // Error, funName must be used in an assign expression. 7a. A function can be defined as both setter and getter, and cumulate both behavior. 7b. property is deprecated and redefined as setter *and* getter for a transitional period. 8. method behave as functions : class A { void foo() {} } A a; static assert(is(typeof(a.foo) : void delegate())); // Pass. &a.foo; // deprecated NOOP for compatibility. a.foo(); // call a.foo 9. UFCS without () are delegate like construct : void foo(T t) {} T t; t.foo; // Is a struct with a function pointer and t. (equivalent to a delegate). The struct member's type is the same as the first argument. If a copy is necessary postblit is called - but will not be called at function call. If foo take a reference, a pointer is stored. t.foo(); // call foo with t as parameter. 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.d : the function/delegate get's called and the result is used as parameter for foo. This eliminate the need for () on all functions of an UFCS chain expect the last one, which is a price to pay for cleanly defined, unambiguous semantic. Waiting for the shitstorm . . .
Jan 24 2013
On 2013-01-24 14:41, deadalnix wrote:3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable. 4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given. 5. setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument. setter void funName(T t) {} T t; funName = t; // function gets executed. funName(t); // Error, funName must be used in an assign expression. 6. setter can as well be used as UFCS : getter void funName(T t, U u) {} T t; U u; t.funName = u; // function gets executed. t.funName(u); // Error, funName must be used in an assign expression.What about property(getter) and property(setter) instead? Otherwise we need two new built-in attributes.8. method behave as functions : class A { void foo() {} } A a; static assert(is(typeof(a.foo) : void delegate())); // Pass. &a.foo; // deprecated NOOP for compatibility. a.foo(); // call a.fooThe address operator wouldn't be needed to get a delegate for a method anymore? -- /Jacob Carlborg
Jan 24 2013
On Thursday, 24 January 2013 at 13:56:03 UTC, Jacob Carlborg wrote:On 2013-01-24 14:41, deadalnix wrote:I don't really care about the syntax. If any new attribute has to be added, they should be defined in some modules instead of builtin.3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable. 4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given. 5. setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument. setter void funName(T t) {} T t; funName = t; // function gets executed. funName(t); // Error, funName must be used in an assign expression. 6. setter can as well be used as UFCS : getter void funName(T t, U u) {} T t; U u; t.funName = u; // function gets executed. t.funName(u); // Error, funName must be used in an assign expression.What about property(getter) and property(setter) instead? Otherwise we need two new built-in attributes.No, which would eliminate the difference behavior between function as variables and function defined in source code. This is a big step forward for functional style.8. method behave as functions : class A { void foo() {} } A a; static assert(is(typeof(a.foo) : void delegate())); // Pass. &a.foo; // deprecated NOOP for compatibility. a.foo(); // call a.fooThe address operator wouldn't be needed to get a delegate for a method anymore?
Jan 24 2013
On 2013-01-24 15:04, deadalnix wrote:No, which would eliminate the difference behavior between function as variables and function defined in source code. This is a big step forward for functional style.Then what do you mean by: &a.foo; // deprecated NOOP for compatibility. -- /Jacob Carlborg
Jan 24 2013
On Thursday, 24 January 2013 at 14:19:34 UTC, Jacob Carlborg wrote:On 2013-01-24 15:04, deadalnix wrote:a.foo is the same as &a.foo . The reason is that &a.foo is used in a lot of code today as it is the only way to perform such action. As a.foo is not an rvalue, it does not conflict. To achieve the ideally consistent behavior it should be disabled at some point.No, which would eliminate the difference behavior between function as variables and function defined in source code. This is a big step forward for functional style.Then what do you mean by: &a.foo; // deprecated NOOP for compatibility.
Jan 24 2013
On 1/24/13 8:41 AM, deadalnix wrote: [snip]Waiting for the shitstorm . . .Nothing like that at least from me but I can plainly say this proposal has merit but will never get implemented. Andrei
Jan 24 2013
On 01/24/2013 12:57 PM, Andrei Alexandrescu wrote:On 1/24/13 8:41 AM, deadalnix wrote: [snip]Wait, so Walter would be willing to ice property, but deprecating it in favor of this meritorious proposal will never happen? I, for one, would love to see good ideas go into the language that I like to use. I'd be willing to s/ property/ getter| setter/ all of my code for this. I wonder how hard it would be to write a tool that does the conversion and gets the disambiguation right in 90% of the cases...Waiting for the shitstorm . . .Nothing like that at least from me but I can plainly say this proposal has merit but will never get implemented. Andrei
Jan 25 2013
On 1/24/2013 5:41 AM, deadalnix wrote:For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.Dang, I hadn't thought of the typeof(funName) issue.
Jan 24 2013
On 1/24/2013 12:23 PM, Walter Bright wrote:On 1/24/2013 5:41 AM, deadalnix wrote:On further thought, if funName is a property, then typeof(funName) should give the return type of the property, not the 'function' type.For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.Dang, I hadn't thought of the typeof(funName) issue.
Jan 24 2013
On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.2. funName() call the function.And if funName is a getter returning delegate?3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable.Agree, but property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given.Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".5. setter is an attribute. A setter method can *only* be used in rhs of an expression. The assigned value is used as argument. setter void funName(T t) {} T t; funName = t; // function gets executed. funName(t); // Error, funName must be used in an assign expression.Disagree, it is inconsistent with getter. property ... funName(T t ... ) should always behave as t.funName property. It is unnecessary complication.6. setter can as well be used as UFCS : getter void funName(T t, U u) {} T t; U u; t.funName = u; // function gets executed. t.funName(u); // Error, funName must be used in an assign expression.And this is exactly the syntax I'd like to see. Again, as void return should be disallowed for getters, no ambiguity here and same property suits just fine.7a. A function can be defined as both setter and getter, and cumulate both behavior.Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.7b. property is deprecated and redefined as setter *and* getter for a transitional period.;)8. method behave as functions : class A { void foo() {} } A a; static assert(is(typeof(a.foo) : void delegate())); // Pass. &a.foo; // deprecated NOOP for compatibility. a.foo(); // call a.fooAgree;9. UFCS without () are delegate like construct : 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.dVery complicated for no real gain. Just prohibit function call without (), including (). Profit!Waiting for the shitstorm . . .Welcome ;)
Jan 25 2013
On Friday, 25 January 2013 at 15:32:13 UTC, mist wrote:On Thursday, 24 January 2013 at 13:41:42 UTC, deadalnix wrote:No adress because : - it would now be impossible to ensure transition using & as NOOP. - this address is useless anyway. That'd be a pointer to a pointer to instructions. I played with that using modified version of SDC, and this is clearly what does work best. If you really need an address, you can do : immutable f = function void() {};For regular functions : 1. funName is the function itself : void funName() {} static assert(is(typeof(funName) == void function())); // Pass. funName has no address, it is equivalent to enum function void() funName = {}; &funName become a NOOP and is deprecated, for compatibility reasons. It is not ambiguous as funName has no address anyway.Agree with differentiation but why no address? For me funName looks like function pointer variable, why prohibiting to cast this to raw address? &funName is legacy, agree.funName is not a getter and don't return a delegate. How a getter behave is explained below. Mixing everything together is the perfect way to create a mess.2. funName() call the function.And if funName is a getter returning delegate?You didn't addressed why property. Answer you gave to point 5 and 6 make me think you aren't aware of the ambiguities property causes with UFCS. Please note that : [1, 2].front and front = [1, 2] are semantically 100% equivalent. I do agree that a getter returning void is weird, but that wasn't really important here.3. getter is an attribute. A function marked getter is automatically executed : () is added automatically : getter void funName() {} funName; // function get executed. funName(); // Error, void is not callable.Agree, but property is enough. I ll insist below that ambiguous cases should be simply an error. And I'd also like to prohibit getters returning void ;)The above code is rewritten ad funName()(t) . That is why you get that error message. The error message goes out before the compiler has even considered funName was used in a call expression. Your proposal may be an improvement for that very case, but isn't in general the error presented above.4. getter can be used as UFCS. getter void funName(T t) {} T t; t.funName; // function gets executed. funName(t); // Error, funName require 1 argument, 0 given.Fine by me, but error message is weird. Better "Error, funName is not usable with free-from syntax".7a is required for 7b to work. That is not complication, that is simplification.7a. A function can be defined as both setter and getter, and cumulate both behavior.Feels like unnecessary complication. But if you want to, simply having both return type and 2 parameters is enough.Many people here disagree. I tend to be amongst thoses people. This specific case imply no ambiguity, and is similar to other simplification D already make like . dereferencing pointers.7b. property is deprecated and redefined as setter *and* getter for a transitional period. 9. UFCS without () are delegate like construct : 10. To allow chain of UFCS calls without () everywhere, an opDispatch is defined in object.dVery complicated for no real gain. Just prohibit function call without (), including (). Profit!
Jan 25 2013
On Friday, 25 January 2013 at 15:57:16 UTC, deadalnix wrote:No adress because : - it would now be impossible to ensure transition using & as NOOP. - this address is useless anyway. That'd be a pointer to a pointer to instructions.Need to think about it.funName is not a getter and don't return a delegate. How a getter behave is explained below. Mixing everything together is the perfect way to create a mess.Well, but it is were good design vs mess of special cases really shines :) Anyway, in this statement by "function" you mean "non-property function", ye?You didn't addressed why property. Answer you gave to point 5 and 6 make me think you aren't aware of the ambiguities property causes with UFCS. Please note that : [1, 2].front and front = [1, 2] are semantically 100% equivalent.Not really as I see it. [1, 2].front // requires signature " property T front(int[])" front = [1, 2] // compile error arr.front = [1, 2] // requires signature " property void front(T, int[])"The above code is rewritten ad funName()(t) .Ah, _now_ I am starting to get your proposal. And do not like it in that regard.Many people here disagree. I tend to be amongst thoses people. This specific case imply no ambiguity, and is similar to other simplification D already make like . dereferencing pointers.Well, then it is probably best to focus on free-form property semantics and leave argument about optional parens and friends - there were enough of them in this topic ;) I'll push for optional ones to the end but hope at least for the solution where ambiguity is consistently resolved.
Jan 25 2013
On Friday, 25 January 2013 at 16:11:53 UTC, mist wrote:That is one case where it matters.funName is not a getter and don't return a delegate. How a getter behave is explained below. Mixing everything together is the perfect way to create a mess.Well, but it is were good design vs mess of special cases really shines :) Anyway, in this statement by "function" you mean "non-property function", ye?So you DO make a difference between setters and getters.You didn't addressed why property. Answer you gave to point 5 and 6 make me think you aren't aware of the ambiguities property causes with UFCS. Please note that : [1, 2].front and front = [1, 2] are semantically 100% equivalent.Not really as I see it. [1, 2].front // requires signature " property T front(int[])" front = [1, 2] // compile error arr.front = [1, 2] // requires signature " property void front(T, int[])"funName(t) is valid if funName returns a delegate. The compiler shouldn't even try to interpret funName(...) as a call of funName.The above code is rewritten ad funName()(t) .Ah, _now_ I am starting to get your proposal. And do not like it in that regard.
Jan 25 2013
On Friday, 25 January 2013 at 16:29:40 UTC, deadalnix wrote:So you DO make a difference between setters and getters.Yes, sure. But I do not need new keywords for that.funName(t) is valid if funName returns a delegate. The compiler shouldn't even try to interpret funName(...) as a call of funName.Yes, I have finally understood how it is intended to work. I just do not like complexity with re-writing funName(t) as funName()(t) and hidden struct creation from function symbols. I cheer any compiling restrictions, but overall type system should be as transparent as possible for normal cases. Like brutal simplicity of my proposal better :) But it is an interesting approach, thank you for the insight.
Jan 25 2013
On Friday, 25 January 2013 at 16:47:56 UTC, mist wrote:On Friday, 25 January 2013 at 16:29:40 UTC, deadalnix wrote:Because you invalidate most legitimate use of a setter.So you DO make a difference between setters and getters.Yes, sure. But I do not need new keywords for that.A struct with a function pointer and data already exists in D. This is called a delegate.funName(t) is valid if funName returns a delegate. The compiler shouldn't even try to interpret funName(...) as a call of funName.Yes, I have finally understood how it is intended to work. I just do not like complexity with re-writing funName(t) as funName()(t) and hidden struct creation from function symbols. I cheer any compiling restrictions, but overall type system should be as transparent as possible for normal cases. Like brutal simplicity of my proposal better :)But it is an interesting approach, thank you for the insight.
Jan 25 2013
On Friday, 25 January 2013 at 16:53:43 UTC, deadalnix wrote:Because you invalidate most legitimate use of a setter.Erm.. Whaaat? How this case is legitimate at all? Please elaborate. In example you define a property for some data type and then try to assign to this property without using any context. It is like calling class method and skipping "this". As I have mentioned in other thread, there are 2 contradictory approaches: either free-form property has semantics of global variable or it has semantics of data member of its first argument. Not both.A struct with a function pointer and data already exists in D. This is called a delegate.And additional hidden implementation complications differ it from all other function types. Rare special case for clearly defined situations. I like it that way. Leave function to be just like good old C function.
Jan 25 2013
No, god no. This would break code AGAIN and still not fix the problems, instead introducing new ones! I think any property proposal that talks about parenthesis in the definition is wrong. With a good definition, the existing type system will handle the parenthesis. property int foo() { return 10; } foo(); // the correct error is "type int is not callable" This is the key point: A property is NOT a function as far as user code is concerned. That's just an implementation detail. As far as user code is concerned, a property IS its return value. If you implement that, leaving all the other rules in the language exactly the same, we'll actually fix some problems without breaking the overwhelming bulk of existing code. Fixing the rest of the problems is then about getting op*Assign to work right. Functions not marked property should NOT change AT ALL from what we have now. I am against removing the existing optional parenthesis rule, and I am against removing the property decoration. Fix it this time, don't break it in a different place.
Jan 24 2013
On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:No, god no. This would break code AGAIN and still not fix the problems, instead introducing new ones! I think any property proposal that talks about parenthesis in the definition is wrong. With a good definition, the existing type system will handle the parenthesis. property int foo() { return 10; } foo(); // the correct error is "type int is not callable" This is the key point: A property is NOT a function as far as user code is concerned. That's just an implementation detail. As far as user code is concerned, a property IS its return value. If you implement that, leaving all the other rules in the language exactly the same, we'll actually fix some problems without breaking the overwhelming bulk of existing code. Fixing the rest of the problems is then about getting op*Assign to work right. Functions not marked property should NOT change AT ALL from what we have now. I am against removing the existing optional parenthesis rule, and I am against removing the property decoration. Fix it this time, don't break it in a different place.I wholeheartedly agree. David
Jan 24 2013
On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:Functions not marked property should NOT change AT ALL from what we have now. I am against removing the existing optional parenthesis rule, and I am against removing the property decoration.I'll be rude, but that is needed. The whole mess we have today is because of this kind of reasoning (note that I'm only talking about the quoted part, the rest of your post is very good). The process goes as follow. 1. Let's add this special case here, this allow for user X to drop few chars in his source file. 2. How, user Y discovered that this interact in a weird way with feature Z. Let's live with it forever/break code/add this little tweak to feature Z to make it work. 3. If break code isn't chosen, much latter, user K notice that bunch of function of phobos don't take into account some corner cases and go crazy due to the tweak above. Phobos is fixed with adding a big amount of complexity or stay broken as it would mess up too much code. All other libs are broken is that case. 4. Current situation.
Jan 24 2013
On Thursday, January 24, 2013 14:43:33 Adam D. Ruppe wrote:No, god no. This would break code AGAIN and still not fix the problems, instead introducing new ones! I think any property proposal that talks about parenthesis in the definition is wrong. With a good definition, the existing type system will handle the parenthesis. property int foo() { return 10; } foo(); // the correct error is "type int is not callable" This is the key point: A property is NOT a function as far as user code is concerned. That's just an implementation detail. As far as user code is concerned, a property IS its return value. If you implement that, leaving all the other rules in the language exactly the same, we'll actually fix some problems without breaking the overwhelming bulk of existing code. Fixing the rest of the problems is then about getting op*Assign to work right. Functions not marked property should NOT change AT ALL from what we have now. I am against removing the existing optional parenthesis rule, and I am against removing the property decoration. Fix it this time, don't break it in a different place.Yes. I think that it's fairly clear that we need to do something like this. Getting rid of property is throwing out the baby with the bathwater. Not having it is a complete mess. And plenty of corner cases have been shown just in this thread which show how not having property causes problems, completely aside from the issue of whether you should be allowed to call functions without parens. Personally, I'd love strict property enforcement, but I think that it's clear at this point that that's not going to fly. However, a solution like this which is effectively weak property enforcement (parens illegal on property functions but optional for normal functions) fixes the worst technical problems caused by the lack of property, and this particular proposal seems like a solid way to go about it. - Jonathan M Davis
Jan 24 2013
Am 24.01.2013 20:14, schrieb Jonathan M Davis:On Thursday, January 24, 2013 14:43:33 Adam D. Ruppe wrote:I see it exactly the same way.No, god no. This would break code AGAIN and still not fix the problems, instead introducing new ones! (...)Yes. I think that it's fairly clear that we need to do something like this. Getting rid of property is throwing out the baby with the bathwater. Not having it is a complete mess. And plenty of corner cases have been shown just in this thread which show how not having property causes problems, completely aside from the issue of whether you should be allowed to call functions without parens. Personally, I'd love strict property enforcement, but I think that it's clear at this point that that's not going to fly. However, a solution like this which is effectively weak property enforcement (parens illegal on property functions but optional for normal functions) fixes the worst technical problems caused by the lack of property, and this particular proposal seems like a solid way to go about it. - Jonathan M Davis
Jan 24 2013
One thing I am interested to hear from ones who think allowing no-parens calls is fine is the following snippet: http://dpaste.1azy.net/cd2f759e ------------------------------------------------------------ import std.stdio; alias Delegate1 = int delegate(); alias Delegate2 = Delegate1 delegate(); Delegate2 func() { writeln("Function"); return (){ writeln("First delegate"); return (){ writeln("Second delegate"); return 42; }; }; } int call(alias func)() { return func; } void main() { writeln("Case 1"); func; writeln("Case 2"); func(); writeln("Case 3"); func()(); writeln("Case 4"); auto tmp = func(); // tmp; // Error: var has no effect in expression (tmp) } ------------------------------------------------------------ Upon any design choice questions should asked: 1) How this should behave to be consistent? 2) Should this error be an error? 3) How much special casing are you ready to throw in? Also I really like an addition with prohibiting to use property functions _with_ parens. Add this to prohibiting no-parens calls for normal ones and you will get my ideal solution, strict and clear. And I still don't see why it won't fly. Yes, it will break user code. No, this is not an issue. At this point it is clear some design mistakes need to be corrected without stockpiling workarounds and one of major goals for new release process was to allow breaking changes with least possible user inconvenience. If it is not the case, then new release process has failed as much as property.
Jan 24 2013
I agree with Adam's view and I really think property is a good thing. APIs have to specify their semantics and clearly distinguish properties from functions, which may be implemented similarly but *mean* different things. Basically a property is a *thing* or a characteristic, normally a noun, whereas a property is an action, normally a verb. As a special case, a property can be a delegate or function, and calling it with () would apply the parens to the delegate (which the user is explicitly calling), but not to the property. Properties as they are can also be used to emulate "indexed properties", as in other languages. If a property's type is a struct that implements [] and []= then we can do: image.pixels[x,y] = Rgb(255,0,0); And yes, I think properties should always be called ["used" I would rather say] without parens, and functions always be called But anyway as I don't develop the compiler, I speak from a distance, and I'm not aware of the implementation complications there may be... On Thursday, 24 January 2013 at 13:43:34 UTC, Adam D. Ruppe wrote:No, god no. This would break code AGAIN and still not fix the problems, instead introducing new ones! I think any property proposal that talks about parenthesis in the definition is wrong. With a good definition, the existing type system will handle the parenthesis. property int foo() { return 10; } foo(); // the correct error is "type int is not callable" This is the key point: A property is NOT a function as far as user code is concerned. That's just an implementation detail. As far as user code is concerned, a property IS its return value. If you implement that, leaving all the other rules in the language exactly the same, we'll actually fix some problems without breaking the overwhelming bulk of existing code. Fixing the rest of the problems is then about getting op*Assign to work right. Functions not marked property should NOT change AT ALL from what we have now. I am against removing the existing optional parenthesis rule, and I am against removing the property decoration. Fix it this time, don't break it in a different place.
Jan 29 2013
29-Jan-2013 17:27, Alvaro пишет:I agree with Adam's view and I really think property is a good thing. APIs have to specify their semantics and clearly distinguish properties from functions, which may be implemented similarly but *mean* different things. Basically a property is a *thing* or a characteristic, normally a noun, whereas a property is an action, normally a verb.A typo pretty much ruined otherwise good point :) -- Dmitry Olshansky
Jan 29 2013
On 24 January 2013 13:40, d coder <dlang.coder gmail.com> wrote:As much as I want to agree, I also feel this comes as too little, too lateNot going to happen. Effectively what is being proposed here is that we are going to be stuck with the current state of property for the next 7 years, and no bugs will be fixed on it as its on deprecation. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';to come to this conclusion now.+1 And therefor we should take out property ASAP :-)
Jan 24 2013
On 1/24/13, Walter Bright <newshound2 digitalmars.com> wrote:2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics.This is going to be a problem in API refactoring. if "f" used to be a field but is now turned into a (potentially) expensive function call, the user will have no idea. Anyway we'll lose track of everything in this thread just like in all the other threads, so I suggest that we: - Create a new branch in DMD which will only be used to work on property freely - Add all test-cases which are affected by this feature - Work on this branch for some time until we get a solid implementation - Discuss property enforcement on a casis-by-casis base in the forums, rather than discussing it wholesome. Special rules should be ok as long as we properly define them and document them. And later we'll merge this into master and add some solid bit of documentation to go with it. Whatever we decide it should be a result of focused work, and not executive decisions due to perceived maintenance costs. We haven't really had a focused effort on properly implementing property, we've had sporadic pull requests instead.
Jan 24 2013
On 01/24/2013 03:34 AM, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I somehow feel like someone read my article from a couple years ago (http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property) and you implemented the less important part and consciously ignored the more important part. The section titled "semantic rewriting of properties" is the important one. Do that. It removes a source of bugs and gives intuitive behavior to our property-functions (ex: prop++; works in general). property is considerably less meaningful: take it or leave it, I certainly won't care. It's a bikeshed full of personal opinions. If we had godly hindsight, then we would have made fields non-addressable by default so that people get safe design behavior by default: non-addressable fields can be turned into properties (assuming property rewriting exists) without breaking API, which creates closure for the whole concept. There would, of course, have to be a way to make it possible to explicitly mark variables as addressable in cases where you need to make pointers to them. That non-addressability semantic might have helped reference-counting too. The mistake's made though; we'll probably just have to take that one in the gut.
Jan 24 2013
On Thu, 24 Jan 2013 02:34:42 -0600, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.vote++
Jan 24 2013
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.clear guidelines and syntax enforcement. I think it's a case of D trying to be TO flexible. Function Calls have Parens. Period. Property Calls do NOT have Parens. Period. It's quick, clean, and easy to parse. for a property consumer the rules are trivial. That's the whole point of properties. In D: Optional parens for everyone! Parsing nightmare for all! I also want to reiterate a point I've seen on this thread. Parens on properties is a very C programmer thing. What is the net effect of forcing properties to have parens? I have to type two more shift-characters to satisfy the compiler because we couldn't be arsed to get the current implementation right. Ehm. That's not how you make a case to newbie... Banish that idea, permanently! Let's consider what a property really is. It's a data encapsulation tool. They allow us to expose object internal data in a safe way. Nuking the idea is a step backwards. While I get that C++ users would immediately be comfortable with the ambiguities of not having a distinct property mechanism, you're going to correct functions the compiler will automagically figure out it's a property. And consider that in not all cases do I want int GetMyData() { } to be callable without parens as you are suggesting here. Although I provide no demo implementation, imagine that this is a non-trivial function that it runs against guidelines.) Now some innocent programmer calls my function as a property not realizing what is really going on and BOOM! He just wrote himself a bug. And yes, i've written code like this before. And before the academics pile on me for it. My job is to write code that gets the job done, being academically correct is for when all other requirements have been satisfied. In the real world, we don't have the luxury of spending a day to make our code ideal. One of the principles of encapsulated data is that accessing the data has zero side-effects. This change makes what is happening ambiguous to the user of the property/function. Ambiguity is bad and will NOT solve our problems. My vote: Fix property. Dropping it will create even more problems and not likely fix many of the current ones. You never solve problems by making the code more ambiguous. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson wrote:Let's consider what a property really is. It's a data encapsulation tool. They allow us to expose object internal data in a safe way. Nuking the idea is a step backwards.This, this and this again. Reading this thread I sometimes get the feeling that part of programmers treat property as a nice way to save 2 extra symbols. Or probably to play with verb/noun meaning. It has different goals from both of those.
Jan 24 2013
On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson wrote:I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
Jan 24 2013
On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:On Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilson wrote:I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
Jan 24 2013
On Thursday, January 24, 2013 21:47:38 mist wrote:On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. Yes, making it so that the property function has a _side-effect_ is a bug, but replacing variables with property functions is not. A classic example of why it's useful is when you refactor a class such that a public variable becomes a calculated value such that it doesn't make sense to have a variable for it anymore. Instead of breaking all of the code that uses the variable by changing it a function, you change it to be a property function, and all of the code which used it continues to compile and work just fine. D's properties need some work before that will really work properly (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=8006 ), but it works just fine - Jonathan M DavisOn Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilsonwrote:I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
Jan 24 2013
On Thu, 24 Jan 2013 13:00:35 -0800, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Thursday, January 24, 2013 21:47:38 mist wrote:++ to Mr. Davis! This is much more concise way of stating what I was trying to say. And it is an argument that should NOT be lightly dismissed, it is a very real, very common problem. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On Thursday, 24 January 2013 at 20:44:33 UTC, eles wrote:Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. Yes, making it so that the property function has a _side-effect_ is a bug, but replacing variables with property functions is not. A classic example of why it's useful is when you refactor a class such that a public variable becomes a calculated value such that it doesn't make sense to have a variable for it anymore. Instead of breaking all of the code that uses the variable by changing it a function, you change it to be a property function, and all of the code which used it continues to compile and work just fine. D's properties need some work before that will really work properly (e.g. http://d.puremagic.com/issues/show_bug.cgi?id=8006 ), but it works just fine - Jonathan M DavisOn Thursday, 24 January 2013 at 20:26:50 UTC, mist wrote:It is a wrong use case for a property. Necessity to change data assignment/access to call of function with side-effect is design error and should be fixed with programmers experience, not property hacks.On Thursday, 24 January 2013 at 20:20:42 UTC, Adam Wilsonwrote:I think the widest spread use case of a property is: you start with a variable as memeber of a class, you write a lot of assignment code, then you decide that you need to do some more extensive processing instead of simple assignment, and all that without breaking existing code. so, you transform the variable into a property. of course, it could happen the other way around (converting a function into a property/variable).
Jan 24 2013
On Thursday, 24 January 2013 at 21:00:49 UTC, Jonathan M Davis wrote:Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. ...Yes, but not just any function. Side-effect free function that controls access to data. And Adam suggested it is fine to use properties to add side-effects to data assignments which is drastically different. I agree with all your words so it is probably just misunderstanding.
Jan 24 2013
On Thu, 24 Jan 2013 13:14:00 -0800, mist <none none.none> wrote:On Thursday, 24 January 2013 at 21:00:49 UTC, Jonathan M Davis wrote:side-effects, but that it runs counter to guidelines. I personally do NOT write properties with side-effects. I was attempting to illustrate in a [much to] concise way why optional parens are bad... -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/Being able to swap out a public variable with a function without having to change any code using it is arguably the primary reasons that property functions exist in the first place. ...Yes, but not just any function. Side-effect free function that controls access to data. And Adam suggested it is fine to use properties to add side-effects to data assignments which is drastically different. I agree with all your words so it is probably just misunderstanding.
Jan 24 2013
"more extensive processing" does not necessarily involve side effects. beside that, as long as those side effects only affects the instance owning that property, nothing is wrong about it. changing a normal member variable could also result in changing the instance's state and behaviour (think that the variable is a flag).
Jan 24 2013
On Thursday, January 24, 2013 00:34:42 Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.Another issue to consider is enhancements such as http://d.puremagic.com/issues/show_bug.cgi?id=8006 As a property function is supposed to be an abstraction for a variable, and you really should be able to swap out property functions and public variables without breaking code, things like foo.prop += 5; and ++foo.prop; should work. Unfortunately, D's current property implementation is poor enough that that code doesn't currently, but that can be fixed in a backwards- compatible-manner. But implementing something like that becomes more problematic without explicit properties (potentially even dangerous, depending on what ends up happening with those sorts of expressions with non- property functions which are called without parens). Maybe it could be done, but it seems to me that it's the sort of thing that should be controlled. We don't want lots of voodoo happening with functions called without parens, as we risk getting some nasty bugs when using functions that weren't really meant to be properties. But we _do_ want some of that voodoo with functions that are designed to be properties. So, I really think that we need to have explicit properties, even if we allow paran-less function calls in some other cases. with properties from the get-go. - Jonathan M Davis
Jan 24 2013
On 01/24/2013 03:45 PM, Jonathan M Davis wrote:On Thursday, January 24, 2013 00:34:42 Walter Bright wrote:I think what you want is semantic property rewriting. Please see this: http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property#SemanticrewritingofpropertiesThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.Another issue to consider is enhancements such as http://d.puremagic.com/issues/show_bug.cgi?id=8006 As a property function is supposed to be an abstraction for a variable, and you really should be able to swap out property functions and public variables without breaking code, things like foo.prop += 5; and ++foo.prop; should work. Unfortunately, D's current property implementation is poor enough that that code doesn't currently, but that can be fixed in a backwards- compatible-manner.But implementing something like that becomes more problematic without explicit properties (potentially even dangerous, depending on what ends up happening with those sorts of expressions with non- property functions which are called without parens). Maybe it could be done, but it seems to me that it's the sort of thing that should be controlled. We don't want lots of voodoo happening with functions called without parens, as we risk getting some nasty bugs when using functions that weren't really meant to be properties. But we _do_ want some of that voodoo with functions that are designed to be properties. So, I really think that we need to have explicit properties, even if we allow paran-less function calls in some other cases. with properties from the get-go. - Jonathan M Davis
Jan 24 2013
On 1/24/13, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.It is super-ironic that you want to simply pull-out and destroy a feature because it wasn't properly defined or implemented, yet you single-handedly introduced UDAs into the language with its own syntax without any prior approval of the community. Will we be making a "UDAs - take it behind the woodshed and shoot it?" thread a year from now?
Jan 24 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.What about code that's always ignored property? int delegate() _del; int delegate() getDelegate() { return _del; } auto del = getDelegate(); // does _del get called? Just a thought, NMS
Jan 24 2013
On Jan 24, 2013, at 1:40 PM, Nathan M. Swan <nathanmswan gmail.com> = wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:somewhere.This has turned into a monster. We've taken 2 or 3 wrong turns =return value taking (), the () go on the return value.=20 Perhaps we should revert to a simple set of rules. =20 1. Empty parens are optional. If there is an ambiguity with the =(one argument). No variadics.=20 2. the: f =3D g rewrite to: f(g) only happens if f is a function that only has overloads for () and =I think a clarification of rule 1 is that parens will be = right-associative. So in your example, _del would be called.==20 3. Parens are required for calling delegates or function pointers. =20 4. No more property.=20 What about code that's always ignored property? =20 =20 int delegate() _del; =20 int delegate() getDelegate() { return _del; } =20 auto del =3D getDelegate(); // does _del get called?
Jan 24 2013
On Thursday, January 24, 2013 13:48:53 Sean Kelly wrote:On Jan 24, 2013, at 1:40 PM, Nathan M. Swan <nathanmswan gmail.com> wrote:I'd argue for simply making it so that the parens are required when a function returns something which is callable. So, getDelegate would be illegal, getDelegate() would return the delegate, and getDelegate()() would call the delegate. - Jonathan M DavisOn Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:I think a clarification of rule 1 is that parens will be right-associative. So in your example, _del would be called.This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.>> 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.What about code that's always ignored property? int delegate() _del; int delegate() getDelegate() { return _del; } auto del = getDelegate(); // does _del get called?
Jan 24 2013
Apart from +=, ++, what breaks compatibility of fields and properties, is that you can't take the address of a property, but of a field (as already mentioned). To increase compatibility and in order to avoid breaking peoples' code, when a field is changed to a property, maybe, simply offer the possibility to declare fields to be a property too, with property. And make it so that the access to such a field behaves exactly the same as to a property: No address taking, and as long as properties don't support ++, +=, ... maybe even forbid those. Example: property int a; would be completely equivalent to: int a_; property int a() { return a_; } property int a(int new_a) { a_=new_a; return a_; } I think this would suffice to make the property concept really sound and working in practice. If, this is considered a good thing, I could create yet another property DIP. Another thing I am wondering, will this still be possible: void myProperty(int a) property {} void function(int) dg=&myProperty; Or in other words, will taking the address of a property method still be possible? I think it would be quite sensible and useful (for e.g. std.signals), taking the address of a transient return value does not make any sense anyway, so no ambiguity here. On the other hand it would break compatibility with fields again. So if we also want to make sure the way back (from property methods to field) works, disallowing taking the address might be the way to go for a finally proper implementation. Best regards, Robert
Jan 24 2013
On Thursday, 24 January 2013 at 22:27:02 UTC, Robert wrote:property int a; would be completely equivalent to: <snip>Not bad.Another thing I am wondering, will this still be possible: void myProperty(int a) property {} void function(int) dg=&myProperty;If I get things my way, no. I'd rewrite that, internally, into &(myProperty()), and then, (unless it returns ref), you'd get an error about can't take address of an rvalue. There'd be no way, under my preference, to treat a property like a function at all.I think it would be quite sensible and usefulIndeed, but there's an easy alternative too that works with both kinds of data, properties and regular: wrapping it in an function at the usage site, e.g. "(a) => myProp = a;"
Jan 24 2013
Yeah, I thought of that and the compiler can optimize it away if not needed. So this would be fine, but see my second, improved proposal. On Thu, 2013-01-24 at 23:37 +0100, Adam D. Ruppe wrote:Indeed, but there's an easy alternative too that works with both kinds of data, properties and regular: wrapping it in an function at the usage site, e.g. "(a) => myProp = a;"
Jan 24 2013
On Thu, 24 Jan 2013 14:26:50 -0800, Robert <jfanatiker gmx.at> wrote:Apart from +=, ++, what breaks compatibility of fields and properties, is that you can't take the address of a property, but of a field (as already mentioned). To increase compatibility and in order to avoid breaking peoples' code, when a field is changed to a property, maybe, simply offer the possibility to declare fields to be a property too, with property. And make it so that the access to such a field behaves exactly the same as to a property: No address taking, and as long as properties don't support ++, +=, ... maybe even forbid those. Example: property int a; would be completely equivalent to: int a_; property int a() { return a_; } property int a(int new_a) { a_=new_a; return a_; } I think this would suffice to make the property concept really sound and working in practice. If, this is considered a good thing, I could create yet another property DIP. Another thing I am wondering, will this still be possible: void myProperty(int a) property {} void function(int) dg=&myProperty; Or in other words, will taking the address of a property method still be possible? I think it would be quite sensible and useful (for e.g. std.signals), taking the address of a transient return value does not make any sense anyway, so no ambiguity here. On the other hand it would break compatibility with fields again. So if we also want to make sure the way back (from property methods to field) works, disallowing taking the address might be the way to go for a finally proper implementation. Best regards, RobertConsider: property int Count { get; set; } A read-write integer property with an automatically implemented getter and setter functions in IL. property int Count { get; } A read-only integer property with an automatically implemented getter function. property int Count { set; } A write-only integer property with an automatically implemented setter function. This is rarely used, but I have seen it. the user code. The getter/setter then work against this field. The one problem with your example is that you haven't defined a way to -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
On 2013-01-24 23:41, Adam Wilson wrote:The one problem with your example is that you haven't defined a way toproperty(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a" -- /Jacob Carlborg
Jan 25 2013
On Fri, 25 Jan 2013 05:00:32 -0800, Jacob Carlborg <doob me.com> wrote:On 2013-01-24 23:41, Adam Wilson wrote:This, for the love of all that is good in the world, a million times this! -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/The one problem with your example is that you haven't defined a way toproperty(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a"
Jan 25 2013
On 2013-01-25 18:12, Adam Wilson wrote:I think this syntax feels quite obvious. -- /Jacob Carlborgproperty(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a"This, for the love of all that is good in the world, a million times this!
Jan 25 2013
On 2013-01-24 23:26, Robert wrote:Apart from +=, ++, what breaks compatibility of fields and properties, is that you can't take the address of a property, but of a field (as already mentioned). To increase compatibility and in order to avoid breaking peoples' code, when a field is changed to a property, maybe, simply offer the possibility to declare fields to be a property too, with property. And make it so that the access to such a field behaves exactly the same as to a property: No address taking, and as long as properties don't support ++, +=, ... maybe even forbid those. Example: property int a; would be completely equivalent to: int a_; property int a() { return a_; } property int a(int new_a) { a_=new_a; return a_; }I really like this. Although this is not really what the rest of the thread is about can could perhaps be introduced separately. What I like about this is that I get a virtual property and doesn't have to write the boiler plate code by hand.I think this would suffice to make the property concept really sound and working in practice. If, this is considered a good thing, I could create yet another property DIP. Another thing I am wondering, will this still be possible: void myProperty(int a) property {} void function(int) dg=&myProperty; Or in other words, will taking the address of a property method still be possible? I think it would be quite sensible and useful (for e.g. std.signals), taking the address of a transient return value does not make any sense anyway, so no ambiguity here. On the other hand it would break compatibility with fields again. So if we also want to make sure the way back (from property methods to field) works, disallowing taking the address might be the way to go for a finally proper implementation.Scala solves the first one by always implementing public instance variables as virtual functions. -- /Jacob Carlborg
Jan 25 2013
Proper property design:property int a;gets actually lowered by the compiler to:int a_; property int a() { return a_; } property int a(int new_a) { a_=new_a; return a_; }-> field property, and get/set property are actually the same thing. -> It is guaranteed that they behave the same way and can always be exchanged. -> Taking the address of the getter/setter also always works, enabling things like connecting the setter to a signal for example. I don't know about you guys, but I love this. It is just perfect. What do I miss? Best regards, Robert
Jan 24 2013
On Thu, 24 Jan 2013 14:47:44 -0800, Robert <jfanatiker gmx.at> wrote:Proper property design:The syntax provides no way to define read-only or write-only properties. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/property int a;gets actually lowered by the compiler to:int a_; property int a() { return a_; } property int a(int new_a) { a_=new_a; return a_; }-> field property, and get/set property are actually the same thing. -> It is guaranteed that they behave the same way and can always be exchanged. -> Taking the address of the getter/setter also always works, enabling things like connecting the setter to a signal for example. I don't know about you guys, but I love this. It is just perfect. What do I miss? Best regards, Robert
Jan 24 2013
There is, just don't do: property int a; but int a_; property int a() { return a_} but adding syntactic sugar later on, if really desired, should not be too hard. On Thu, 2013-01-24 at 14:48 -0800, Adam Wilson wrote:The syntax provides no way to define read-only or write-only properties.
Jan 24 2013
On 2013-01-24 23:48, Adam Wilson wrote:The syntax provides no way to define read-only or write-only properties.property(get, set) int a; property(get) int b; property(set) int c; property int d; // same as "a" -- /Jacob Carlborg
Jan 25 2013
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I want to point out another usage of properties that invades my work every day. Consider: public partial class CustomerXAML : DependencyObject { public Guid ID { get { return (Guid)GetValue(IDProperty); } set { SetValue(IDProperty, value); } } public static readonly DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(Guid), typeof(CustomerXAML), null); } Where: public class DependencyObject { public object GetValue(DependencyProperty prop); public void SetValue(DependencyProperty prop, object value); } What does this code say? I am dealing with data or calling a function? Well to those of you not familiar with WPF/XAML's Dependency pattern let me explain. You're doing both. You see XAML uses something that for lack of a better term I will call a "sparse memory model". Another way to describe it is to say that the DependencyObject stores ONLY the values that have been changed from the default value. They had to do this because their object model is ridiculous and they needed over a gigabyte of RAM just to instantiate all the objects required to draw an empty window. They discovered that most of the values in the object didn't change from the defaults. However, the changes had to be stored in a Dictionary (think Map) for speed, that's what all the typeof's in the Register function are for. And storing/retrieving those directly from the Map would have lead to all sorts of problems. So GetValue/SetValue handle that for you and allows them to do much more, like databinding and update callbacks. My point is this. This does not violate encapsulation, we ARE working with just DATA, but we want to hide the implementation details of HOW we are working with said data, and in this case we CANNOT use a simple backing field. From a user perspective CustomerXAML.ID is JUST data FIELD. But behind the scenes it's a bit more complicated than that. THAT is the power of properties. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I just worked through this with Alexander Bothe (of Mono-D fame). Here is public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/
Jan 24 2013
On 1/24/13 6:52 PM, Adam Wilson wrote:On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This looks essentially the same as Walter's proposal. AndreiThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
Jan 24 2013
On 01/25/2013 01:12 AM, Andrei Alexandrescu wrote:On 1/24/13 6:52 PM, Adam Wilson wrote:Not at all. Walter's proposal just chooses the other option when stuff is "ambiguous" and adds a hideous special rule in case the empty argument list was obtained from an empty sequence.On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This looks essentially the same as Walter's proposal. AndreiThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
Jan 24 2013
On Thu, 24 Jan 2013 16:29:24 -0800, Timon Gehr <timon.gehr gmx.ch> wrote:On 01/25/2013 01:12 AM, Andrei Alexandrescu wrote:Basically this. I was writing a longer post that essentially said this. Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/On 1/24/13 6:52 PM, Adam Wilson wrote:Not at all. Walter's proposal just chooses the other option when stuff is "ambiguous" and adds a hideous special rule in case the empty argument list was obtained from an empty sequence.On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This looks essentially the same as Walter's proposal. AndreiThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I just worked through this with Alexander Bothe (of Mono-D fame). Here public Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.
Jan 24 2013
On 1/24/13 7:36 PM, Adam Wilson wrote:Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize.Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
Jan 24 2013
On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 1/24/13 7:36 PM, Adam Wilson wrote:I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize.Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
Jan 24 2013
On 1/24/13 9:54 PM, Adam Wilson wrote:On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Again, the question needs asking: is it a given that we need to allow optional parentheses? Otherwise we'll keep on rehashing this over and over again. AndreiOn 1/24/13 7:36 PM, Adam Wilson wrote:I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn.Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize.Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
Jan 24 2013
On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote:Again, the question needs asking: is it a given that we need to allow optional parentheses? Otherwise we'll keep on rehashing this over and over again.I hate optional parentheses with a passion, but I think that it's quite clear that too many people want them (including many who want property) and that too much code will break if we make the change. I think that we can reach a consensus on how property should function, but we'll never get a consensus that optional parentheses should be done away with. So, yes. I think that we can move forward with the assumption that optional parens are here to stay (much as I don't personally like that). - Jonathan M Davis
Jan 24 2013
On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote: I hate optional parentheses with a passion, but I think that it's quite clear that too many people want them (including many who want property) and thatI hate the optional parentheses (I really see no point for this except in to!"conversions" but that's templates), I want not understand why those two issues are so difficult to accept and implement.
Jan 24 2013
On Friday, 25 January 2013 at 06:47:30 UTC, eles wrote:On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:Seriously, who wants to try criticizing this?: http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx Just provide serious answers why we cannot do that in D.On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote:
Jan 24 2013
On Friday, 25 January 2013 at 06:54:15 UTC, eles wrote:On Friday, 25 January 2013 at 06:47:30 UTC, eles wrote:"Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields." I think that having *clear* properties in D is worthing.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:On Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote:
Jan 24 2013
On Friday, January 25, 2013 07:47:27 eles wrote:On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:The issue is that lots of people like optional parentheses. I expect that even if there were no support for properties in the language whatsoever, the folks who like to be able to elide parens would still like that and want it. However, even if we're stuck with parenless function calls being legal, we can without parens. It's just that many function calls would be able to look like they were getter properties if they're called without parens. But because of the tons of arguments over property (many of them really being over parenless function calls rather than property itself) and the fact that Andrei has never liked the idea of property in the first place, Walter and Andrei seem to be trying to get rid of it and simplify the language - hence this thread. So, we're forced to argue in favor of property. At this point, I think that the best that we can hope for is 1. Parenless function calls will continue to function essentially as they have been. 2. It will be illegal to use a non- property function as a setter. 3. property will be kept, and property functions must be called without parens. If we go that route, we may also be able to make some improvements to property functions to make them closer to how variables are (e.g. make a.prop += 1 valid), and property functions will be able to be essentially as they are in calls. - Jonathan M DavisOn Thursday, January 24, 2013 22:52:36 Andrei Alexandrescu wrote: I hate optional parentheses with a passion, but I think that it's quite clear that too many people want them (including many who want property) and thatI hate the optional parentheses (I really see no point for this except in to!"conversions" but that's templates), I want not understand why those two issues are so difficult to accept and implement.
Jan 24 2013
On Friday, 25 January 2013 at 07:14:19 UTC, Jonathan M Davis wrote:On Friday, January 25, 2013 07:47:27 eles wrote:I think the root reason of this fight over what properties are and how are used/usable boils down to the way they are deined in 1. in D they are defined as functions (or very similarily to those), so many people are perceiving them as FUNCTIONS to which one tries to stick some variable-like calls people tend to see those as some variables with some extra. IMHO the chosen syntax for defining properties matters in the first place. I do not dear to suggest implementing a more variable-like syntax of the barricade we wand D's properties to be.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M DavisHowever, even if we're stuck with parenless function calls being legal, we can that it be used without parens.
Jan 25 2013
On Friday, January 25, 2013 09:49:00 eles wrote:On Friday, 25 January 2013 at 07:14:19 UTC, Jonathan M Davis wrote:better, but it's too late now. But a lot of the problem stems from the fact that the original way that properties were implemented in D was essentially what Walter is proposing now, and I believe that the fact that that worked originally was at least partially by accident. So, it's pretty much always been the case in D that properties were implemented via functions, and any probably would have been a good idea). - Jonathan M DavisOn Friday, January 25, 2013 07:47:27 eles wrote:I think the root reason of this fight over what properties are and how are used/usable boils down to the way they are deined in 1. in D they are defined as functions (or very similarily to those), so many people are perceiving them as FUNCTIONS to which one tries to stick some variable-like calls people tend to see those as some variables with some extra. IMHO the chosen syntax for defining properties matters in the first place. I do not dear to suggest implementing a more variable-like syntax of the barricade we wand D's properties to be.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M DavisHowever, even if we're stuck with parenless function calls being legal, we can that it be used without parens.
Jan 25 2013
On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them. :-)I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:Delphi has no real functional capabilities.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
On 01/27/2013 12:35 PM, deadalnix wrote:On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:What about scala?On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:Delphi has no real functional capabilities.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
On Sunday, 27 January 2013 at 13:16:59 UTC, Timon Gehr wrote:On 01/27/2013 12:35 PM, deadalnix wrote:I'm not a scala specialist (however, one of my coworker is, so I'll ask him tomorrow) but my understanding is that that autocall functionality in scala is more limited than in D.On Sunday, 27 January 2013 at 11:18:01 UTC, sclytrack wrote:What about scala?On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:Delphi has no real functional capabilities.On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:In Delphi they are also optional and nobody uses them. However, everybody else doesn't use them.I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
int CoolThing { in; out; } - auto property without implementation; int CoolThing { private in; out; } - private setter; public getter; int CoolThing { in { _privateCoolThing = value * 42; } out { return 42; } } Explicit calling: void in_CoolThing(int); int out_CoolThing(); Proper "Property rewrite" can be implemented. Property CoolThing looks like code contract for _privateCoolThing. So it's maybe + or -. --no-parenthesis for current behaviour for non-property functions.
Jan 27 2013
On 2013-01-27 12:20, Michael wrote:int CoolThing { in; out; } - auto property without implementation; int CoolThing { private in; out; } - private setter; public getter; int CoolThing { in { _privateCoolThing = value * 42; } out { return 42; } } Explicit calling: void in_CoolThing(int); int out_CoolThing(); Proper "Property rewrite" can be implemented. Property CoolThing looks like code contract for _privateCoolThing. So it's maybe + or -. --no-parenthesis for current behaviour for non-property functions.Won't this conflict with contracts, which also uses the "in" and "out" keywords? -- /Jacob Carlborg
Jan 27 2013
On Sunday, 27 January 2013 at 12:07:35 UTC, Jacob Carlborg wrote:Won't this conflict with contracts, which also uses the "in" and "out" keywords?As suggestion:Property CoolThing looks like code contract for _privateCoolThing. So it's maybe + or -.
Jan 27 2013
On Sunday, 27 January 2013 at 10:54:05 UTC, SomeDude wrote:On Friday, 25 January 2013 at 04:21:07 UTC, Jonathan M Davis wrote:If that's the level of abstraction on which you want to discuss about optional parentheses, then I could say that "I love optional parentheses", and since "Love conquers all", my argument would win against your argument. But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue. Then, it will be obvious to you which identifiers are variables and which are function calls based on their color. In this situation it will feel silly to have to write those empty parentheses, because they don't make the code any less ambiguous (it's already perfectly unambiguous because of the colors) and, infact, those empty parentheses make the code (a bit) harder to read.I hate optional parentheses with a passion - Jonathan M DavisSame here.
Jan 27 2013
On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue. Then, it will be obvious to you which identifiers are variables and which are function calls based on their color. In this situation it will feel silly to have to write those empty parentheses, because they don't make the code any less ambiguous (it's already perfectly unambiguous because of the colors) and, infact, those empty parentheses make the code (a bit) harder to read.If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
Jan 27 2013
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:You're being an extremist here. From a vim user and automagic function call hater as well ;) First many reliable code have been written in Java. Quite a lot of it in fact. And refusing IDE help make no real sense. Even vim is an IDE, and not a simple editor.But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue. Then, it will be obvious to you which identifiers are variables and which are function calls based on their color. In this situation it will feel silly to have to write those empty parentheses, because they don't make the code any less ambiguous (it's already perfectly unambiguous because of the colors) and, infact, those empty parentheses make the code (a bit) harder to read.If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
Jan 27 2013
On Sunday, 27 January 2013 at 13:56:53 UTC, deadalnix wrote:You're being an extremist here. From a vim user and automagic function call hater as well ;) First many reliable code have been written in Java. Quite a lot of it in fact. And refusing IDE help make no real sense. Even vim is an IDE, and not a simple editor.Probably, but that is a result of general mainstream moving to IDE-reliance. You need to sound somewhat radical to be noticed :) I did not say Java is not _reliable_. I have said it is not _expressive_ on language level and relies on boilerplate generation by IDE for something as basic as properties. I do not use vim as an IDE - no plugins, no clever macros, no ctags etc. Any editor with file list, syntax highlighting and tabs works for me; it just happens that it is more convenient to use vim when you mostly do console stuff anyway. That may come from the fact of having most commercial experience in large teams with huge legacy codebases - readability and support issues take there >90% of time and efforts, contrary to actually coding. Made me interested in languages that do enforce such stuff at language level.
Jan 27 2013
On 1/27/13 8:56 AM, deadalnix wrote:On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:Language adoption is a complex phenomenon with many variables, and it's easy to neglect certain aspects when assessing the impact of others. Java started as a well-designed language albeit small and underpowered. It enjoyed the benefit of unwavering support from a large corporation and an estimated one billion dollars in marketing budget. (I remember in 1998 non-programming managers in NYC were talking "we must adopt Java!" without even knowing what Java meant. Java may as well be the only programming language in history to enjoy management support before programmer support.) That has caused Java to evolve quite differently from languages with grass-roots support (e.g. C++, Ruby, PHP, or Python). Generally the latter languages grew with little tooling support aside from the traditional Unix toolset, and that is to some extent reflected in the languages themselves. are available for dedicated tooling support. It would have evolved differently otherwise, and I assume many people would have a dimmer view AndreiOn Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:You're being an extremist here. From a vim user and automagic function call hater as well ;) First many reliable code have been written in Java. Quite a lot of it in fact. And refusing IDE help make no real sense. Even vim is an IDE, and not a simple editor.But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue. Then, it will be obvious to you which identifiers are variables and which are function calls based on their color. In this situation it will feel silly to have to write those empty parentheses, because they don't make the code any less ambiguous (it's already perfectly unambiguous because of the colors) and, infact, those empty parentheses make the code (a bit) harder to read.If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed. Relying on IDE features is what made Java unusable for expressive, robust code. I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad. 2 cents from vim user and optional parens hater here.
Jan 27 2013
On Sunday, 27 January 2013 at 14:26:20 UTC, Andrei Alexandrescu wrote:resources are available for dedicated tooling support. It would have evolved differently otherwise, and I assume many people use it with vim and emacs.That is kind of my point : such language is made for tooling. With the 2 side of the medal : tooling is great, because language have been made with tooling in mind, but coding without tooling is not the best experience. Not that tremendous efforts are put now to introduce tooling in because C++ is tooling hostile. I know resource are a factor. But clearly not the only one. Doing some tooling on Java is braindead simple, the compiler provide everything you need to reuse it/parts of it.
Jan 27 2013
On 01/27/2013 09:26 AM, Andrei Alexandrescu wrote:Language adoption is a complex phenomenon with many variables, and it's easy to neglect certain aspects when assessing the impact of others.Indeed it is, as you show below.Java started as a well-designed language albeit small and underpowered. It enjoyed the benefit of unwavering support from a large corporation and an estimated one billion dollars in marketing budget. (I remember in 1998 non-programming managers in NYC were talking "we must adopt Java!" without even knowing what Java meant. Java may as well be the only programming language in history to enjoy management support before programmer support.)First off, where do you get this billion dollar marketing figure from? I've seen it from you before, with no citation, and could find no such citation myself when doing a Web search. Second, Java was a "right place, right time" language. It was initially pegged for consumer devices, and was part of a bid to get cable company adoption for a TV add-on device, but when that fell flat it occurred to them the Web was a good fit. It was (in theory, but not in practice -- Flash ended up winning the browser), the hype machine exploded, and the rest is history. For example, if you read this article here: http://vidlar.powweb.com/internett/the-java_net/history.html ...you'll see their growth was fairly organic. Yes, I'm sure they had a marketing budget, but I highly doubt that in 1998 they were spending $1 billion.That has caused Java to evolve quite differently from languages with grass-roots support (e.g. C++, Ruby, PHP, or Python). Generally the latter languages grew with little tooling support aside from the traditional Unix toolset, and that is to some extent reflected in the languages themselves.One thing you're missing about Java is that because of it's simplicity of design and static typing, it was so easy to write tools for. No crazy macros or templates, and lots of type information.are available for dedicated tooling support. It would have evolved differently otherwise, and I assume many people would have a dimmer viewan IDE out of the box from Sun. For many it was emacs or whatever, then there was JBuilder (from Borland), and then IBM and IntelliJ, etc.
Jan 27 2013
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed.Why is it an indicator of that?I may use an IDE help when I need to learn architecture level connections in new project, but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad.Notepad opens text files. There is nothing that says that the source files of X programming language must be text files. It's just a convention, not a law or a real limitation in designing languages. Therefore you can't assume that an X source file can be opened and read with notepad. Someone might design a language that wouldn't rely on those symbols that just happen to be found on keyboards, but instead, relied more on text formatting and colors.
Jan 27 2013
On Sunday, 27 January 2013 at 14:11:13 UTC, TommiT wrote:On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:Because it fails to maintain and control semantics on its own.If we require clever IDE to distinguish visually something as basic as data semantics and callable semantics it is an indicator language design is screwed.Why is it an indicator of that?Notepad opens text files. There is nothing that says that the source files of X programming language must be text files. It's just a convention, not a law or a real limitation in designing languages.Text is still most efficient form of providing information. Please call me back when something better will be invented. Then we can speak about minimal editing environment for it.
Jan 27 2013
On Sunday, 27 January 2013 at 14:14:18 UTC, Dicebot wrote:Text is still most efficient form of providing information. Please call me back when something better will be invented. Then we can speak about minimal editing environment for it.Okay, here's what I invented in 5 minutes that would be better than plain text: * Arguments to a function call would go, instead of inside parentheses, inside a box with a solid, black border and some nice and unique background color. * Template arguments would go in a box with a hatched border line and a different background color. * Blocks are, instead of surrounded by braces, indicated by this thing that looks like a tall, black, thin, right-opening square bracket that spans the whole block and sits directly to the left of the left-most characters of the statements inside the block. * Instead of having '*' indicate both "multiply" and "dereference", invent and use a new symbol that means "dereference". The same goes for all symbols, like '&', '!', '~', ' ', that don't have a universally defined meaning that corresponds to its meaning in language X. In order to input those "things that are not symbols found on your keyboard", you'd either need to learn keyboard shortcuts by heart, or use a custom keyboard, which is what tv and movie editors have done for 20 years with their Avid keyboards. Most other creative jobs require custom tools for performing the craft, why not programming?
Jan 27 2013
On Sunday, 27 January 2013 at 15:09:10 UTC, TommiT wrote:On Sunday, 27 January 2013 at 14:14:18 UTC, Dicebot wrote:And how it is any better? Also D sources are unicode, so last two are possible just now and you need no special keyboard for it. Still the same good old text.Text is still most efficient form of providing information. Please call me back when something better will be invented. Then we can speak about minimal editing environment for it.Okay, here's what I invented in 5 minutes that would be better than plain text: * Arguments to a function call would go, instead of inside parentheses, inside a box with a solid, black border and some nice and unique background color. * Template arguments would go in a box with a hatched border line and a different background color. * Blocks are, instead of surrounded by braces, indicated by this thing that looks like a tall, black, thin, right-opening square bracket that spans the whole block and sits directly to the left of the left-most characters of the statements inside the block. * Instead of having '*' indicate both "multiply" and "dereference", invent and use a new symbol that means "dereference". The same goes for all symbols, like '&', '!', '~', ' ', that don't have a universally defined meaning that corresponds to its meaning in language X. In order to input those "things that are not symbols found on your keyboard", you'd either need to learn keyboard shortcuts by heart, or use a custom keyboard, which is what tv and movie editors have done for 20 years with their Avid keyboards. Most other creative jobs require custom tools for performing the craft, why not programming?
Jan 27 2013
On Sunday, 27 January 2013 at 15:22:34 UTC, Dicebot wrote:And how it is any better? Also D sources are unicode, so last two are possible just now and you need no special keyboard for it. Still the same good old text.I don't know if what I invented is any better, but my attempt was to make something that's easier to read and less ambiguous than plain text. For example parenthesis would be used only to define the order in which expressions are evaluated, and _not_ to indicate a section of arguments. But are you really arguing that: "there can be nothing better than plain text for programmers to declare their intent". I wonder why we even have graphic operating systems, if graphic elements don't make thing easier to use and understand. To me, saying that "D is bad language, because in order to most effectively write and understand the code requires some dedicated software" is like saying "Avid is a bad editing software, because using it most effectively requires some custom keyboard". You can write and understand D code, where parentheses of nullary function calls have been omitted, in notepad - it just may not be most optimal environment. Just like you can use Avid with a regular keyboard, it just may not be most optimal to do so (unless you remember all the keys by heart already).
Jan 27 2013
On Sun, Jan 27, 2013 at 04:42:39PM +0100, TommiT wrote: [...]But are you really arguing that: "there can be nothing better than plain text for programmers to declare their intent". I wonder why we even have graphic operating systems, if graphic elements don't make thing easier to use and understand.[...] I wonder the same thing too. I'm a CLI fanatic. ;-) And in fact, I honestly find GUI's a pain to use, due to their non-scriptability and needless reliance on the rodent. Yes, it makes things more appealing to the eye, but easier to use is arguable (there are too many GUI apps out there that are clearly written by people who have no idea what UI design means), and ease of understanding is also questionable (ever used a GUI app with icons that require clairvoyance to figure out what it means?). Some tasks are more suited for GUI interfaces, like image editing, 3D modelling, etc.. But I find GUIs to be an unnecessary waste of resources on most other tasks. But yes, I know I'm in the minority, and I'm quite OK with that. T -- The trouble with TCP jokes is that it's like hearing the same joke over and over.
Jan 27 2013
On Sunday, 27 January 2013 at 15:42:40 UTC, TommiT wrote:On Sunday, 27 January 2013 at 15:22:34 UTC, Dicebot wrote:More noise -> not easier to read. It may has a merit when designing grammar unambiguous for reader with limited symbol count is impossible but otherwise simple unambiguous representation beats complex one. Also your proposal is not very different from plain text, it is about on the level of syntax highlighting. We do have graphic operating systems and power users still do use consoles/shells for advanced operating system-related work. Because graphic elements are easier to understand, but harder (less efficient) to use. I am perfectly fine with relaxed mouse clicking when I am browsing or watching films or whatever, but when I do work - please, give me a pair of my trusted text shells. I don't know what Avid is but if it requires custom keyboard for proper usage - it is either bad or targeted to users with weak computer competence (and googling shows it is some audio editing stuff, this second option is likely).And how it is any better? Also D sources are unicode, so last two are possible just now and you need no special keyboard for it. Still the same good old text.I don't know if what I invented is any better, but my attempt was to make something that's easier to read and less ambiguous than plain text. For example parenthesis would be used only to define the order in which expressions are evaluated, and _not_ to indicate a section of arguments. But are you really arguing that: "there can be nothing better than plain text for programmers to declare their intent". I wonder why we even have graphic operating systems, if graphic elements don't make thing easier to use and understand. To me, saying that "D is bad language, because in order to most effectively write and understand the code requires some dedicated software" is like saying "Avid is a bad editing software, because using it most effectively requires some custom keyboard". You can write and understand D code, where parentheses of nullary function calls have been omitted, in notepad - it just may not be most optimal environment. Just like you can use Avid with a regular keyboard, it just may not be most optimal to do so (unless you remember all the keys by heart already).
Jan 27 2013
On Sunday, 27 January 2013 at 15:59:42 UTC, Dicebot wrote:I don't know what Avid is but if it requires custom keyboard for proper usage - it is either bad or targeted to users with weak computer competence (and googling shows it is some audio editing stuff, this second option is likely).I was referring to Avid video editing software, which has been used for pretty much all movies and tv series made since 1990. There you can see the custom keyboard in its natural environment: http://meganandtimmy.com/wp-content/uploads/2012/04/Avid.jpeg But this is getting really far from the subject now.
Jan 27 2013
On Sun, Jan 27, 2013 at 04:09:09PM +0100, TommiT wrote: [...]Most other creative jobs require custom tools for performing the craft, why not programming?Because it's not *necessary*. Having a universal representation has many advantages, *independence* from custom tools, scriptability, testability, etc.. Independence from specialized tools, contrary to popular opinion, is a very good thing. Having a universal representation like text lets *anyone* write tools for it easily, and more importantly, tools that can work with more than just that specific representation. This is incentive for people to actually invest the effort to make said tools, because the target market is much wider (==lower risk, greater ROI). It also lets more tools than the creators of the thing being represented thought of to be used for manipulating it -- i.e., saves them the effort of reinventing an entire ecosystem, you just leverage what's already out there. Having specialized representations means that far fewer tools can be used for manipulating it, and these tools must be specifically made for the job. Why artificially limit yourself in this way, when generic formats and generic tools are far more useful? Always reminds me of the difficulty of automating the test of GUI apps. You need specialized software to record interactions and replay them, whereas with a text-based interface, you can *generate* test cases that no human has ever done before, thereby making it possible to have more complete coverage than would be possible with any record/replay-based system. GUI apps are also non-scriptable, which greatly limits their usability in automated environments. Recorded GUI scripts are also usually in a non-interoperable format, which makes sharing / editing by others, etc., more difficult than necessary. Obligatory quote: A program should be written to model the concepts of the task it performs rather than the physical world or a process because this maximizes the potential for it to be applied to tasks that are conceptually similar and, more important, to tasks that have not yet been conceived. -- Michael B. Allen I see many more disadvantages to things like colors, fonts, reliance on specific tools, than advantages. Things that artificially limit themselves for no good reason other than convenience are rarely worth the trouble. (Caveat: I'm another slobbering vim fanatic. I don't even use syntax highlighting. So you may take a big grain of salt with everything I say. :-P) T -- The richest man is not he who has the most, but he who needs the least.
Jan 27 2013
On 01/27/13 15:11, TommiT wrote:There is nothing that says that the source files of X programming language must be text files. It's just a convention, not a law or a real limitation in designing languages. Therefore you can't assume that an X source file can be opened and read with notepad. Someone might design a language that wouldn't rely on those symbols that just happen to be found on keyboards, but instead, relied more on text formatting and colors.Except we're not talking about such hypothetical language, but one where text *is* the natural form for source code. It also happens to be called "D", which means that it will be universally expected to have certain properties. Something can be a great idea in one context, while being an extremely bad one in another. artur
Jan 27 2013
On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:... but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad.I think we have been throwing the term ambiguous around too carelessly. Obviously code must be semantically unambiguous when viewed in a Notepad. I don't think that's an issue with optional parentheses - the issue is just that it's "not as easy to read", which I don't think means the same as ambiguous (I'm sure about all english words though). "Not as easy to read" shouldn't sound nearly as bad as ambiguous - it's just a little inconvenience that can be gotten rid of by using an IDE that does semantic colorization.
Jan 27 2013
On Sunday, 27 January 2013 at 17:19:15 UTC, TommiT wrote:On Sunday, 27 January 2013 at 13:42:33 UTC, Dicebot wrote:"easy to read" == "I can find part of code that interests me easily" "unambiguous" == "I can understand semantics of code I have just read with as little additional context as possible" Ambiguity is mentioned often because there is one for compiler and one for programmer. Those two are sometimes similar but rather different in nature.... but at scope level semantics for reader should be perfectly clear and unambiguous even if opened in notepad.I think we have been throwing the term ambiguous around too carelessly. Obviously code must be semantically unambiguous when viewed in a Notepad. I don't think that's an issue with optional parentheses - the issue is just that it's "not as easy to read", which I don't think means the same as ambiguous (I'm sure about all english words though). "Not as easy to read" shouldn't sound nearly as bad as ambiguous - it's just a little inconvenience that can be gotten rid of by using an IDE that does semantic colorization.
Jan 27 2013
On 01/27/2013 06:33 PM, Dicebot wrote:... "unambiguous" == "I can understand semantics of code I have just read with as little additional context as possible" ...In order to do that, it is necessary aware of the precise definitions, or at least specifications, of referenced declarations in any case. So by your definition, the current function call syntax is "unambiguous".
Jan 27 2013
On 01/28/2013 12:34 AM, Timon Gehr wrote:On 01/27/2013 06:33 PM, Dicebot wrote:to be... "unambiguous" == "I can understand semantics of code I have just read with as little additional context as possible" ...In order to do that, it is necessaryaware of the precise definitions, or at least specifications, of referenced declarations in any case. So by your definition, the current function call syntax is "unambiguous".
Jan 27 2013
On Sunday, 27 January 2013 at 23:34:59 UTC, Timon Gehr wrote:In order to do that, it is necessary aware of the precise definitions, or at least specifications, of referenced declarations in any case. So by your definition, the current function call syntax is "unambiguous".Sure, it is for compiler. And it for me if I check the definition of symbol. But without going to some other source file and looking up definition there is no way to guess if this: ----- auto ret = something.anything; ----- ..actually does anything else but reassigning a field to a variable. In my personal experience time lost to check such stuff out is much more than time saved by fast and convenient parens-less coding. Thus the attitude.
Jan 28 2013
On Monday, 28 January 2013 at 08:14:45 UTC, Dicebot wrote:Sure, it is for compiler. And it for me if I check the definition of symbol.However, as long as we have properties *at all* you'd have to property syntax, it is still possible .anything is a function call.
Jan 28 2013
On Monday, 28 January 2013 at 13:30:33 UTC, Adam D. Ruppe wrote:On Monday, 28 January 2013 at 08:14:45 UTC, Dicebot wrote:No, I am repeating this again and again - when I see a property I need to think it is a variable. It is intended fooling of the reader and reason to have properties. Thus no checking in that case, I just assume it is a field or variable or anything like that. And if I'll spend few days debugging the case that comes down to my colleague has designed a property that does not behave like a field - I'll go and politely ask to stop doing this. May be also will punch him. Problem solved.Sure, it is for compiler. And it for me if I check the definition of symbol.However, as long as we have properties *at all* you'd have to property syntax, it is still possible .anything is a function call.
Jan 28 2013
On Monday, 28 January 2013 at 13:34:33 UTC, Dicebot wrote:And if I'll spend few days debugging the case that comes down to my colleague has designed a property that does not behave like a field - I'll go and politely ask to stop doing this.Do you consider a dynamic arrays' length property to be a good, properly designed property: array.length = 7; It does behave like a field, but it's got pretty serious side effects that you just need to know about. And, I don't see much point in having properties that are not allowed to have any side-effects.
Jan 28 2013
On Monday, 28 January 2013 at 16:45:57 UTC, TommiT wrote:Do you consider a dynamic arrays' length property to be a good, properly designed property:No.And, I don't see much point in having properties that are not allowed to have any side-effects.Then you need something other than properties.
Jan 28 2013
On 1/28/13 11:50 AM, Dicebot wrote:On Monday, 28 January 2013 at 16:45:57 UTC, TommiT wrote:Wait, so you're against any writable properties? Maybe there's a confusion somewhere. AndreiDo you consider a dynamic arrays' length property to be a good, properly designed property:No.And, I don't see much point in having properties that are not allowed to have any side-effects.Then you need something other than properties.
Jan 28 2013
On Monday, 28 January 2013 at 16:59:40 UTC, Andrei Alexandrescu wrote:Wait, so you're against any writable properties? Maybe there's a confusion somewhere. AndreiAh, yes, there is a confusion between "side-effect" from the pure function point of view and "side-effect" from property functionality point of view. I'd say that property setter should be a pure function with one exception : it is allowed to changed "this" fields. No global state changes, no calls to impure global functions, not even calls to "this" non-property functions.
Jan 28 2013
On 2013-01-28 18:11, Dicebot wrote:Ah, yes, there is a confusion between "side-effect" from the pure function point of view and "side-effect" from property functionality point of view. I'd say that property setter should be a pure function with one exception : it is allowed to changed "this" fields. No global state changes, no calls to impure global functions, not even calls to "this" non-property functions.What about getters and setters and gets and sets a value from a cache? -- /Jacob Carlborg
Jan 28 2013
On Monday, 28 January 2013 at 19:43:39 UTC, Jacob Carlborg wrote:On 2013-01-28 18:11, Dicebot wrote: What about getters and setters and gets and sets a value from a cache?Would not have made them properties either. It is somewhat similar to cache and const vs logical const issue. But you are right, this is were personal preferences start varying a lot, I don't realistically hope someone will give me language that restrictive in its core for my needs :) Just expressing personal attitude because I am in the hospital, bored and have a crazy amount of free time to chat on newsgroup :) That may sound weird but I do like when core language features are very restrictive and require programmer to express his intentions verbosely. And provide _possibility_ to do cool stuff via advanced clearly separated advanced features. Like safe vs system but for syntactic language features. Not gonna convince anyone but at least pushing it my way makes me feel good :)
Jan 28 2013
On Monday, 28 January 2013 at 16:50:27 UTC, Dicebot wrote:I think you're putting too much faith on the power of convention and on the similarity between your's and everybody else's notions of how much side effects a settable property can have while not giving the user any surprises. Let's say your type has three properties: Changing any one of those properties must (logically) change at least one other property. Therefore, you can't just pretend that properties are simple data fields.And, I don't see much point in having properties that are not allowed to have any side-effects.Then you need something other than properties.
Jan 28 2013
On Monday, 28 January 2013 at 17:14:31 UTC, TommiT wrote:On Monday, 28 January 2013 at 16:50:27 UTC, Dicebot wrote:That is no different from volatile variables. My notion is at rare. It all comes from "property == variable" mantra.I think you're putting too much faith on the power of convention and on the similarity between your's and everybody else's notions of how much side effects a settable property can have while not giving the user any surprises. Let's say your type has three properties: Changing any one of those properties must (logically) change at least one other property. Therefore, you can't just pretend that properties are simple data fields.And, I don't see much point in having properties that are not allowed to have any side-effects.Then you need something other than properties.
Jan 28 2013
On Monday, 28 January 2013 at 17:30:40 UTC, Dicebot wrote:If you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.Let's say your type has three properties: Changing any one of those properties must (logically) change at least one other property. Therefore, you can't just pretend that properties are simple data fields.That is no different from volatile variables.should be not that rare. It all comes from "property == variable" mantra.I'm just saying that when you read some code written by some person X, you can't rely on person X having the same notion of what properties should be as you do. For this reason you can't only read the documentation of methods and skip reading the documentation of properties, because properties may do/change things that you wouldn't have made them do/change.
Jan 28 2013
On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:If you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
Jan 28 2013
On Mon, Jan 28, 2013 at 07:04:21PM +0100, Dicebot wrote:On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:In the dinosaur age of Motorola 6502 processors, writing certain values to certain "magic" memory addresses triggers side-effects like switching the console into graphics mode. One could argue this is bad design, but it *is* a precedent for side-effects when assigning values to what can be thought of as "just a variable". By comparison, array.length is pretty tame (no visible side-effects except that the array becomes longer). T -- Life is too short to run proprietary software. -- Bdale GarbeeIf you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
Jan 28 2013
On Monday, 28 January 2013 at 18:10:33 UTC, H. S. Teoh wrote:By comparison, array.length is pretty tame (no visible side-effects except that the array becomes longer).... *and* possibly relocated in memory, so that it no longer aliases any other slices originally pointing to the same chunk of data. This is the main reason why .length looks far to innocent in my regard - although I don't really feel strongly about the issue. David
Jan 28 2013
On Monday, 28 January 2013 at 18:04:22 UTC, Dicebot wrote:T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.The question "what is or should be a property?" is a question of semantics. I don't see what performance or those implementation details you mentioned have to do with semantics. What if our container type wasn't a dynamic array? Let's say it's a pseudo container that pretends to be a vector of consecutive int values, but in reality it just has two integers which denote the beginning and the end of the range. Now changing the length property of that container takes constant time (it just sets the end value anew).
Jan 28 2013
On 1/28/13 1:04 PM, Dicebot wrote:On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:I guess you hate if people want their bigints to assign with a = b. AndreiIf you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
Jan 28 2013
On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu wrote:On 1/28/13 1:04 PM, Dicebot wrote:widget.height = 100 should be condemned, too - it changes the state of the entire GUI system. Let's face it: there are *no* objective criteria for determining whether a mutator should be a function or property setter.On Monday, 28 January 2013 at 17:52:45 UTC, TommiT wrote:I guess you hate if people want their bigints to assign with a = b. AndreiIf you think my example of {start_time, end_time, duration} represents proper use of properties, then I don't see why you oppose array.length. To me it seems like the same thing. Array has some length, and you can change it by changing its length property. T represents a certain time range, and you can change it by changing any of its three properties {start_time, end_time, duration} which describe that time range.T changes its inner encapsulated states. Period. It is no different that properties that calculate result on the fly, like range.empty (which is good property usage). Array.length allocates. Takes from some global resources, takes some considerable time, calls some global allocating function. For me it is a crucial difference that pushes symbol to the world of functions.
Jan 28 2013
On Monday, 28 January 2013 at 21:03:04 UTC, Max Samukha wrote:Let's face it: there are *no* objective criteria for determining whether a mutator should be a function or property setter.Yes, but also it's should be a lightweight action (main idea). As proposal: http://forum.dlang.org/post/ydcjggoibjmuuoobgrvq forum.dlang.org http://msdn.microsoft.com/en-us/library/w86s7x04.aspx http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx and quote--no-parenthesis for current behaviour for non-property functions.
Jan 28 2013
On Monday, 28 January 2013 at 21:54:21 UTC, Michael wrote:On Monday, 28 January 2013 at 21:03:04 UTC, Max Samukha wrote:I think we need something more measurable than lightweight-ness to justify a language feature.Let's face it: there are *no* objective criteria for determining whether a mutator should be a function or property setter.Yes, but also it's should be a lightweight action (main idea).As proposal: http://forum.dlang.org/post/ydcjggoibjmuuoobgrvq forum.dlang.org http://msdn.microsoft.com/en-us/library/w86s7x04.aspx http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx and quote--no-parenthesis for current behaviour for non-property functions.
Jan 29 2013
On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu wrote:I guess you hate if people want their bigints to assign with a = b.Have never used bigints. You mean that copy construction upon assignment allocates too? Yes, I do now like this, too, but see no sane to get around this as it will feel unnatural either way. Arrays, however, will not suffer at all from switching to array.resize(42) syntax from array.length = 42 syntax.
Jan 28 2013
On 1/28/13 4:32 PM, Dicebot wrote:On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu wrote:So maybe it's time to adjust your preferences.I guess you hate if people want their bigints to assign with a = b.Have never used bigints. You mean that copy construction upon assignment allocates too? Yes, I do now like this, too, but see no sane to get around this as it will feel unnatural either way.Arrays, however, will not suffer at all from switching to array.resize(42) syntax from array.length = 42 syntax.Well I think this is a given now. So again - time to adjust preferences :o). Andrei
Jan 28 2013
On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu wrote:On 1/28/13 4:32 PM, Dicebot wrote:My feeling is that the array.length getter/setter problem is affected by the perceived assymetry between the getter and the setter operation. Even more, that feeling is exacerbated by the involvment of a canonical type. People expect some expensive background operations for user-defined, complicated types, but not for canonical types. Properties too, are plagued by this, but at least there the choice is explicitly marked and assumed. As for the a=b bigInts vs the array.length=5 problem: the former operation affects the content of a and b. The latter not only affects the content of array.length, but also the very content of array itself. I know the border is thin, however, it exists at the psychological level, since many will gladly accept reallocation in a=b, but not in array.length=5. Maybe is just the power of habit. Maybe not.On Monday, 28 January 2013 at 18:43:19 UTC, Andrei Alexandrescu wrote: Arrays, however, will not suffer at all from switching to array.resize(42) syntax from array.length = 42 syntax.Well I think this is a given now. So again - time to adjust preferences :o).
Jan 28 2013
On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu wrote:So maybe it's time to adjust your preferences.Ye, I know, I speak too much :( Sure, switching to low profile mode.
Jan 29 2013
On Tuesday, 29 January 2013 at 10:26:54 UTC, Dicebot wrote:On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu wrote:Reason and reasonable trade-off should prevail.So maybe it's time to adjust your preferences.Ye, I know, I speak too much :( Sure, switching to low profile mode.
Jan 29 2013
On 1/29/13 5:26 AM, Dicebot wrote:On Monday, 28 January 2013 at 21:43:25 UTC, Andrei Alexandrescu wrote:That's not the right conclusion. AndreiSo maybe it's time to adjust your preferences.Ye, I know, I speak too much :( Sure, switching to low profile mode.
Jan 29 2013
On Sunday, 27 January 2013 at 13:24:31 UTC, TommiT wrote:But, joking aside, I think that all hate against optional parentheses stems from the increase of ambiguity they indisputably cause. However, let's imagine a future where your perfect D IDE paints function calls red, and variables blue.That is not good because in functional style, you manipulate function like variable.
Jan 27 2013
On Friday, 25 January 2013 at 03:52:36 UTC, Andrei Alexandrescu wrote:On 1/24/13 9:54 PM, Adam Wilson wrote:It is NOT and workaround have been proposed to solve the UFCS () invasion case, which is probably the only one that don't boil down to lazyness when digging a little.On Thu, 24 Jan 2013 18:00:06 -0800, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Again, the question needs asking: is it a given that we need to allow optional parentheses? Otherwise we'll keep on rehashing this over and over again.On 1/24/13 7:36 PM, Adam Wilson wrote:I would argue that given how common they already are, cost of the wart is far smaller than the benefit of not having the unique-to-D special case that makes the language that much harder to learn.Also non-logical special case rules like this make the language harder to learn, therefore harder to evangelize.Definitely. But it shouldn't be forgotten that syntactic warts are also a liability. Andrei
Jan 24 2013
On Friday, 25 January 2013 at 00:12:48 UTC, Andrei Alexandrescu wrote:On 1/24/13 6:52 PM, Adam Wilson wrote:in D. So, it is nit Walter's proposal, it is property proposal.On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This looks essentially the same as Walter's proposal.
Jan 25 2013
On 1/25/13 3:10 AM, eles wrote:On Friday, 25 January 2013 at 00:12:48 UTC, Andrei Alexandrescu wrote:Agreed. AndreiOn 1/24/13 6:52 PM, Adam Wilson wrote:So, it is nit Walter's proposal, it is property proposal.On Thu, 24 Jan 2013 00:34:42 -0800, Walter Bright <newshound2 digitalmars.com> wrote:This looks essentially the same as Walter's proposal.
Jan 25 2013
On 2013-01-25 01:12, Andrei Alexandrescu wrote:This code contains explicit properties. Walter's proposal was to remove the explicit properties. -- /Jacob Carlborgpublic Action temp { get; set; } public Action Event { get { return temp; } } t.Event; //returns the delegate t.Event(); //calls the delegate. Simple, clean, clear, concise. No problems with optional parens.This looks essentially the same as Walter's proposal.
Jan 25 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.4. No more property.I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property. On another note, To properly correct this situation we will break code. So before you get started be sure to try out the new feature preview release approach :)
Jan 24 2013
On Thu, 24 Jan 2013 16:34:44 -0800, Jesse Phillips <Jessekphillips+D gmail.com> wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:The problem is that the moment we start talking about property the optional parens people (colloquially referred to henceforth as "your side") start jumping in and attacking us about how removing optional parens would make your sides lives utter misery. I don't even notice the extra parens any more. But most importantly, the syntax is ambiguous to neither the compiler or myself, I know at a subconscious level what I am looking at.) However, the property issue can be addressed without removing your sides optional parens. Adam Ruppe is working on just such a fix right now. Everyone just needs to relax and take a chill pill (or a shot of whiskey if that's your thing). -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.4. No more property.I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property. On another note, To properly correct this situation we will break code. So before you get started be sure to try out the new feature preview release approach :)
Jan 24 2013
On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:However, the property issue can be addressed without removing your sides optional parens. Adam Ruppe is working on just such a fix right now.Well, not right now - I made progress on it a while ago and hit a snag. Can't work on it now because I'm actually behind schedule on an important work product that is coming up on a deadline in a few weeks. I can waste a few minutes to argue, but a few hours or days to hack dmd is a no go right now.
Jan 24 2013
On Thu, 24 Jan 2013 16:47:34 -0800, Adam D. Ruppe <destructionator gmail.com> wrote:On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:I know how that is. No worries. My misunderstanding. -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/However, the property issue can be addressed without removing your sides optional parens. Adam Ruppe is working on just such a fix right now.Well, not right now - I made progress on it a while ago and hit a snag. Can't work on it now because I'm actually behind schedule on an important work product that is coming up on a deadline in a few weeks. I can waste a few minutes to argue, but a few hours or days to hack dmd is a no go right now.
Jan 24 2013
On 01/25/2013 01:42 AM, Adam Wilson wrote:... day. I don't even notice the extra parens any more. But most importantly, the syntax is ambiguous to neither the compiler or myself, I know at a subconscious level what I am looking at.) ...working in other languages.
Jan 24 2013
On Friday, 25 January 2013 at 00:43:46 UTC, Adam Wilson wrote:The problem is that the moment we start talking about property the optional parens people (colloquially referred to henceforth as "your side") start jumping in and attacking us about how removing optional parens would make your sides lives utter misery.Well, I'd hope property could give the compiler enough information to give syntax that matches fields. That hasn't happened yet so I don't see it worth keeping. And if the property syntax has to be changed from a function I'd consider it a failure too. That said many that want property, want optional parens to die, as shown by your side comment that follows.freaking, day. I don't even notice the extra parens any more. But most importantly, the syntax is ambiguous to neither the compiler or myself, I know at a subconscious level what I am looking at.)I haven't had to deal with reading much other peoples code in D or Ruby, so I don't have much information on the readability challenges from one side or the other, but so far my experience has been that it doesn't matter. And while it is a hot topic, D has had it for a long time and no real evidence it is a big problem has risen. (Only the return a delegate from a function)
Jan 25 2013
On Friday, 25 January 2013 at 16:43:45 UTC, Jesse Phillips wrote: [...]That said many that want property, want optional parens to die, as shown by your side comment that follows.I think that observation pins the whole debate down, and it's an incredible amount of debate for something that boils down little more than personal taste. We don't even need property-like behavior, it's not that important. Meanwhile really serious problems exist that are not being attended to. The concept of a property works perfectly fine without explicit property enforcement (except for perhaps an edge case or two that can be corrected). When I started with D, the TDPL told me that I had to put property in, and it was actually a relief to discover that I did not have to do that. It's a waste of time, and more than half the time I could not decide if I wanted property-like behavior or not, so the lack of enforcement was a plus for me. If the default behavior is optional parens plus no property enforcement, i.e., the current behavior, then for the people who want to change the default behavior need to specify property and we implement enforcement for those situations. However, for the remaining functions, the property behavior is optional and not enforced, so some means such as the function proposal will be needed to enforce the traditional c-like function call syntax. But is there any real need for the extra complications of implementing property and c-style function call enforcement? This is D and there's no law that states that D must behave exactly like C. I think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one. If Walter's proposal is not sound, then we need real clear technical reasons why enforcement is required, as opposed to arguments that boil down to personal tastes. --rt
Jan 25 2013
On Friday, 25 January 2013 at 17:17:11 UTC, Rob T wrote:I think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one.The reason property exists in the first place is to fix the edge cases. It got screwed up beyond all recognition by the parenthesis debate, extending its effect well, well beyond the edge case... but that *was* why it was introduced in the first place.
Jan 25 2013
On Friday, 25 January 2013 at 17:24:23 UTC, Adam D. Ruppe wrote:On Friday, 25 January 2013 at 17:17:11 UTC, Rob T wrote:So historically, the fist implementation of the property concept was through a syntax change, allowing removal of empty parens for the getter and assignment syntax for the setter. But due to edge cases, property was conjured up to solve them through property syntax enforcement. The syntax change was partially implemented without property enforcement leaving it optional, and this brought on the big debate concerning enforcement of parens. Why was a partial implementation of an experimental half-backed idea released into the wild? In the future, we can avoid messes like this through a better design and development process with a little planning behind it. The property feature would have remained in experimental mode until most or all of the debate had been settled, then moved into beta for usage trials, and finally into a production release with no more debate and no more bugs or broken edge cases remaining. --rtI think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one.The reason property exists in the first place is to fix the edge cases. It got screwed up beyond all recognition by the parenthesis debate, extending its effect well, well beyond the edge case... but that *was* why it was introduced in the first place.
Jan 25 2013
On Friday, 25 January 2013 at 18:00:24 UTC, Rob T wrote:So historically, the fist implementation of the property concept was through a syntax change, allowing removal of empty parens for the getter and assignment syntax for the setter.That was actually before my time. The optional parens feature has been in D for as long as I can remember; it was there well before 1.0. But yeah, property was added a few years ago over concerns about a small handful of edge cases.Why was a partial implementation of an experimental half-backed idea released into the wild?This is the reason it is on a compiler switch, -property, instead of the main language. Without -property, the property decoration is ignored. (And with -property, it doesn't do anything useful. The implementation is basically: -property: break my code property: please don't break this code It doesn't fix a single thing, and IIRC the implementor knew it; he just put it in as a first step toward something more complete.)
Jan 25 2013
On 2013-01-25 19:00, Rob T wrote:Why was a partial implementation of an experimental half-backed idea released into the wild?It seems just to be how things are done in the D community. Another recent example of this is the UDA that popped up and got implemented from nowhere. -- /Jacob Carlborg
Jan 26 2013
On Saturday, 26 January 2013 at 13:28:46 UTC, Jacob Carlborg wrote:On 2013-01-25 19:00, Rob T wrote:Why was a partial implementation of an experimental half-backed idea released into the wild?It seems just to be how things are done in the D community. Another recent example of this is the UDA that popped up and got implemented from nowhere.
Jan 26 2013
On Saturday, 26 January 2013 at 13:28:46 UTC, Jacob Carlborg wrote:Another recent example of this is the UDA that popped up and got implemented from nowhere.That design is almost identical to a discussion we had a few months ago about it though; the timing was a surprise, but it wasn't bungled the way property was.
Jan 26 2013
On 2013-01-26 17:26, Adam D. Ruppe wrote:That design is almost identical to a discussion we had a few months ago about it though; the timing was a surprise, but it wasn't bungled the way property was.Not the syntax. Walter added a two syntaxes one deprecated using brackets and the one we're using now with the at sign and parentheses. -- /Jacob Carlborg
Jan 26 2013
On 1/25/13 12:17 PM, Rob T wrote:On Friday, 25 January 2013 at 16:43:45 UTC, Jesse Phillips wrote: [...]I agree with all of the above. There has been a fair amount of rationalization and appeal to emotion on all sides. It would be great to get back to reason and clearly compartmentalize objective arguments (of which there have been a few very profound ones) and personal preference. On the objective side there are a few challenges that have been well discussed: 1. Syntactic and semantic implications of properties that return callable entities 2. Introspection, how does one distinguish between a genuine field and a property when necessary 3. Impact on existing and future code On the subjective side, Walter's and my opinion and experience have been largely aligned. With that in mind but speaking for myself unless otherwise noted, here are some bits of my subjective opinion: 1. In C and C++ the syntax "func" or "object.method" does nothing interesting or useful. In C, "func" is actually equivalent with "&func". In C it's actually worse, "func" yields the type "reference to function" which is highly restricted and obeys some rather arcane rules (in particular it's implicitly convertible to pointer to function). C has no methods so the syntax "object.method" does not apply to it. In C++, "object.method" is probably the oddest construct in the entire language: it returns a type that exists but has no name, is not expressible syntactically, is not first class (one can't assign "object.method" to a variable), and has only two allowed operations: take address or apply the function call operator "()". Various C++ implementations have extensions that fix this. Both Walter and I consider these serious lapses in language design. Two of the most accessible elements of syntax do things of considerably low interest and use. I hope I now clarified why I have a dim view of arguments that - implicitly or explicitly - assume the C or C++ behavior in this area is an example to follow on technical grounds. (Clearly, familiarity is a much better argument.) 2. I have tried to add property appropriately in Phobos, in particular for ranges: struct SomeRange { property bool empty(); property ref T front(); void popFront(); } There's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap. I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax. 3. Whatever we do going forward should be _simple_ but not _simplistic_. Right now it's easy to forget that we're all close to the subject. We have it in working memory (at least it's what I think about all the time) and any incremental complexity is an easy cost to absorb intellectually. But when we need to teach this to newcomers or even approach it again with a "cold cache", any undue complexity will be jarring. 4. Whether we like it or not, backward compatibility is an issue. The parens or no parens aspect upon a function call is too ubiquitous to write off as an obscure circumstance. So I don't think the obscurity argument applies. Granted, there are several ways to approach the compatibility issue, all with their specific tradeoffs. All I'm saying is that careful considerations of compatibility must be integral to whatever we do about this. 5. This is a matter in which reasonable people may disagree. For better or worse Walter and to a lesser extent myself are in the position to decide. We're doing the best to gather, mind, and integrate opinions and suggestions but clearly no decision that would please everyone. So please bear with us. I understand this may be frustrating but the best we all can do is think beyond our own preference and on behalf of the larger community. Thanks, AndreiThat said many that want property, want optional parens to die, as shown by your side comment that follows.I think that observation pins the whole debate down, and it's an incredible amount of debate for something that boils down little more than personal taste. We don't even need property-like behavior, it's not that important. Meanwhile really serious problems exist that are not being attended to. The concept of a property works perfectly fine without explicit property enforcement (except for perhaps an edge case or two that can be corrected). When I started with D, the TDPL told me that I had to put property in, and it was actually a relief to discover that I did not have to do that. It's a waste of time, and more than half the time I could not decide if I wanted property-like behavior or not, so the lack of enforcement was a plus for me. If the default behavior is optional parens plus no property enforcement, i.e., the current behavior, then for the people who want to change the default behavior need to specify property and we implement enforcement for those situations. However, for the remaining functions, the property behavior is optional and not enforced, so some means such as the function proposal will be needed to enforce the traditional c-like function call syntax. But is there any real need for the extra complications of implementing property and c-style function call enforcement? This is D and there's no law that states that D must behave exactly like C. I think Walters proposal to shoot property is perfectly sound. Get rid of it, fix the edge cases, and move on to solving the problems that matter a whole lot more than this one. If Walter's proposal is not sound, then we need real clear technical reasons why enforcement is required, as opposed to arguments that boil down to personal tastes.
Jan 25 2013
Am Fri, 25 Jan 2013 14:59:58 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:I agree with all of the above. There has been a fair amount of rationalization and appeal to emotion on all sides. It would be great to get back to reason and clearly compartmentalize objective arguments (of which there have been a few very profound ones) and personal preference.Do that on this wiki page: http://wiki.dlang.org/Property_Discussion_Wrap-upThere's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap.I think it actually makes sense. I even tried writing ranges for std.digest where front was not a property but a field and was surprised it didn't work. (isInputRange shouldn't check for property. It should check for "can be used like a field" which means field+property.).I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax.Please read the wiki page. popFront or popFront() is orthogonal to the property discussion.3. Whatever we do going forward should be _simple_ but not _simplistic_. Right now it's easy to forget that we're all close to the subject. We have it in working memory (at least it's what I think about all the time) and any incremental complexity is an easy cost to absorb intellectually. But when we need to teach this to newcomers or even approach it again with a "cold cache", any undue complexity will be jarring.Wiki page, wiki page ;-)4. Whether we like it or not, backward compatibility is an issue. The parens or no parens aspect upon a function call is too ubiquitous to write off as an obscure circumstance. So I don't think the obscurity argument applies. Granted, there are several ways to approach the compatibility issue, all with their specific tradeoffs. All I'm saying is that careful considerations of compatibility must be integral to whatever we do about this.The approach described on the wiki does break some code, but that code shouldn't compile anyway: property functions with wrong number of arguments and similar stuff. Only controversial thing is taking the address of a property, but I can't think of a solution which would work well with generic code so I'd just say forbid that.5. This is a matter in which reasonable people may disagree. For better or worse Walter and to a lesser extent myself are in the position to decide. We're doing the best to gather, mind, and integrate opinions and suggestions but clearly no decision that would please everyone.Would be nice if the arguments for the final decision are added to the wiki page :-)
Jan 25 2013
On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu wrote:2. I have tried to add property appropriately in Phobos, in particular for ranges:These are examples of why I'm firmly in the pro-optional parenthesis camp. With them, stuff like this becomes irrelevant; it works either way. But, remember, the problem property needs to solve is none of this. There's no pressing reason to put it on range functions. My view is property maybe somewhat rare in usage: if in doubt, do NOT use it. But there's cases where there is no doubt, and we don't want to throw the baby out with the bathwater there. One example where I'd love property: a dynamic object. Suppose we extend Variant to work Javascript style: Variant v; v.prop = function() { }; v.prop(); // we expect this to call the function, not return a reference to it That would be an property.... range.popFront doesn't need to be. It works fine with the existing optional parenthesis rule.
Jan 25 2013
2 cents regarding your position on " property" usage in phobos: 1) You can always use shorter syntax: property: int func1(); int func2(); ... 2) D is not scripting language (primarily) and as such should value issues related to long-term large code base support more than saving some typing in declaration. It is slightly similar to strong vs weak typing. That is not gonna convince you but I hope this will be taken into consideration somehow.
Jan 25 2013
On Friday, 25 January 2013 at 21:51:14 UTC, mist wrote:2 cents regarding your position on " property" usage in phobos: 1) You can always use shorter syntax: property: int func1(); int func2(); ...This already works property { int func1(); int func2(); } --rt
Jan 25 2013
On Friday, January 25, 2013 23:04:58 Rob T wrote:On Friday, 25 January 2013 at 21:51:14 UTC, mist wrote:They both already work and have do so for ages. - Jonathan M Davis2 cents regarding your position on " property" usage in phobos: 1) You can always use shorter syntax: property: int func1(); int func2(); ...This already works property { int func1(); int func2(); }
Jan 25 2013
On Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis wrote:They both already work and have do so for ages. - Jonathan M DavisErm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
Jan 25 2013
On Friday, January 25, 2013 23:23:50 mist wrote:On Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis wrote:I know. I was responding to Rob's post which implied that the syntax you gave didn't currently work. - Jonathan M DavisThey both already work and have do so for ages. - Jonathan M DavisErm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
Jan 25 2013
On Friday, 25 January 2013 at 22:39:07 UTC, Jonathan M Davis wrote:On Friday, January 25, 2013 23:23:50 mist wrote:I misread the post by mist, I incorrectly thought that it was a new syntax proposal as I did not know about property:. --rtOn Friday, 25 January 2013 at 22:15:51 UTC, Jonathan M Davis wrote:I know. I was responding to Rob's post which implied that the syntax you gave didn't currently work. - Jonathan M DavisThey both already work and have do so for ages. - Jonathan M DavisErm? Yes, and thus it was an answer to "you need to mess every function declaration with an annotation"
Jan 25 2013
On Friday, January 25, 2013 23:56:24 Rob T wrote:I misread the post by mist, I incorrectly thought that it was a new syntax proposal as I did not know about property:: works works with any function attribute, as does {}. - Jonathan M Davis
Jan 25 2013
On 2013-01-26 02:48, Jonathan M Davis wrote:: works works with any function attribute, as does {}.And even for user defined attributes :) -- /Jacob Carlborg
Jan 26 2013
On Friday, January 25, 2013 14:59:58 Andrei Alexandrescu wrote:2. I have tried to add property appropriately in Phobos, in particular for ranges: struct SomeRange { property bool empty(); property ref T front(); void popFront(); } There's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap. I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax.That's simply a question of being able to make function calls without parens. That's different from the question of properties, much as there may be syntactic similarities. While properties do involve not using parens, there's a lot more to them than simply not using parens. A property function is fundamentally different from a normal function by its very nature, not just by its call syntax. A property is an abstraction for a variable (and therefore should be swappable with a variable), whereas a function is explicitly an action. So, regardless of what we do with parenless function calls, getting rid of explicit properties will have serious side effects.5. This is a matter in which reasonable people may disagree. For better or worse Walter and to a lesser extent myself are in the position to decide. We're doing the best to gather, mind, and integrate opinions and suggestions but clearly no decision that would please everyone. So please bear with us. I understand this may be frustrating but the best we all can do is think beyond our own preference and on behalf of the larger community.If we throw away property, then it will be impossible to swap between using variables and property functions, which is one of the main purposes of properties. For instance, it should be possible for a range's front to be variable if that range doesn't need a function for it. There are currently implementation problems with property which prevent us from being able to do that with property, but they can be fixed. However, without explicit properties of some kind, it's just not possible. Not only are the semantics of a property function still too different from a variable (e.g. += doesn't yet work with a property function), but the issue of parens on property functions is a problem. We need to able to make it so that it's illegal to use parens on a property function, not only so that you could potentially swap it out for a public variable if the function was no longer needed but more importantly so that generic APIs (such as ranges) can guarantee that using a variable instead of a property function will work (e.g. if you can call front with parens, then front can never be an actual variable). And for that, you need explicit properties, not just the syntactic sugar of being allowed to drop parens. Also, too much of this discussion has focused on getters. property also has a large impact with setter properties. Without it, you'll be able to do stuff like range.popFrontN = 7; "hello".icmp = "world"; "/usr/bin".buildPath = "dmd"; which makes no sense. As long as we have explicit properties, we can restrict the setter syntax to functions that are actually properties and could conceivably be replaced with variables. Without them, arbitrary functions could be set as if they were variables, many (most?) of which would make absolutely no sense as variables under any circumstances. Keeping parenless functions is one thing, but getting rid of explicit properties is another thing altogether. - Jonathan M Davis
Jan 25 2013
On 1/25/2013 2:14 PM, Jonathan M Davis wrote:A property function is fundamentally different from a normal function by its very nature, not just by its call syntax.I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Jan 25 2013
Walter Bright wrote:For example, even accessing a global variable isn't straightforward, if you look under the hood.Depending on the education under the hood is always a turing machine, Lisp, pseudo code, ... -manfred
Jan 25 2013
On Saturday, 26 January 2013 at 05:39:05 UTC, Walter Bright wrote:On 1/25/2013 2:14 PM, Jonathan M Davis wrote:Walter, that's not how TLS variables are generally implemented in C/C++. They're *normal* variables, placed in a special section of the executable, which is automatically switched in and out on every context switch by the OS. This is true on Windows, and I believe in Linux as well (http://stackoverflow.com/questions/2459692)A property function is fundamentally different from a normal function by its very nature, not just by its call syntax.I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Jan 25 2013
On 1/25/2013 10:06 PM, Mehrdad wrote:Walter, that's not how TLS variables are generally implemented in C/C++.Since I implemented them, I know how they work.They're *normal* variables, placed in a special section of the executable, which is automatically switched in and out on every context switch by the OS.This is not necessarily true at all. It isn't for OSX, for example, and there's nothing in the semantics of TLS which preclude calling a function.
Jan 25 2013
On Saturday, 26 January 2013 at 07:25:24 UTC, Walter Bright wrote:On 1/25/2013 10:06 PM, Mehrdad wrote:I wasn't being pedantic. That's why I said generally, not always. Obviously you can implement things a million different ways...Walter, that's not how TLS variables are generally implemented in C/C++.Since I implemented them, I know how they work.Again, I didn't say they're "necessarily" true either, hence why I mentioned Linux and Windows specifically. OS X is really the odd one out here, not Windows or Linux. But you missed my point, which was, yes, a lot of things COULD contain function calls. Even the two lines int i = 0; i++; COULD contain a function call, but how is that in any shape or form relevant to the discussion about property in any way? Generally, it isn't a function call, and as far as the code is concerned, it isn't a function call. The fact that you may have happened to implement something as a function call doesn't mean anything with regards to the difference between a function call and a direct access for the _programmer_.They're *normal* variables, placed in a special section of the executable, which is automatically switched in and out on every context switch by the OS.This is not necessarily true at all. It isn't for OSX, for example, and there's nothing in the semantics of TLS which preclude calling a function.
Jan 25 2013
On 1/25/2013 11:52 PM, Mehrdad wrote:The fact that you may have happened to implement something as a function call doesn't mean anything with regards to the difference between a function call and a direct access for the _programmer_.I.e. the difference is purely a contrivance, which was my point.
Jan 26 2013
On Saturday, 26 January 2013 at 09:04:47 UTC, Walter Bright wrote:On 1/25/2013 11:52 PM, Mehrdad wrote:Yes, that the whole point of abstraction. It happen that variables and functions are both very useful ones.The fact that you may have happened to implement something as a function call doesn't mean anything with regards to the difference between a function call and a direct access for the _programmer_.I.e. the difference is purely a contrivance, which was my point.
Jan 26 2013
On 2013-01-26 08:52, Mehrdad wrote:Again, I didn't say they're "necessarily" true either, hence why I mentioned Linux and Windows specifically. OS X is really the odd one out here, not Windows or Linux.They can be implemented as a function call on (at least) Linux as well. It's depends on which model is used. Which model is used then depends on various things like who the compiler is able to optimize and dynamic libraries are involved or not. Mac OS X chose the easiest way out and implemented only one mode. A model that works in all cases, and that is a function call. -- /Jacob Carlborg
Jan 26 2013
Am Fri, 25 Jan 2013 21:38:44 -0800 schrieb Walter Bright <newshound2 digitalmars.com>:On 1/25/2013 2:14 PM, Jonathan M Davis wrote:Although variable access might be implemented as a non-trivial function calls everyone tries to make these as fast as possible. Think of PLT/GOT or the TLS register on ARM processors. And this is the difference between variable/property and function: Access to the former has to be 'fast'. There's no real definition of fast in this case, but I doubt an O(n^2) implementation of TLS or variable access in general would be acceptable to anyone.A property function is fundamentally different from a normal function by its very nature, not just by its call syntax.I would have agreed with you on that for years, simply taking its veracity as an axiom, but lately I am not convinced at all of that assertion. I suspect the differences between a property, field, and method are purely contrivance. For example, even accessing a global variable isn't straightforward, if you look under the hood. If it's in a DLL or TLS, there may be a function call in there that is non-trivial.
Jan 26 2013
On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu wrote:1. Syntactic and semantic implications of properties that return callable entitiesI don't understand why this is a special case in the first place. It should behave just like a variable of the same type, period.C has no methods so the syntax "object.method" does not apply to it. In C++, "object.method" is probably the oddest construct in the entire language: it returns a type that exists but has no name, is not expressible syntactically, is not first class (one can't assign "object.method" to a variable), and has only two allowed operations: take address or apply the function call operator "()". Various C++ implementations have extensions that fix this. Both Walter and I consider these serious lapses in language design. Two of the most accessible elements of syntax do things of considerably low interest and use. I hope I now clarified why I have a dim view of arguments that - implicitly or explicitly - assume the C or C++ behavior in this area is an example to follow on technical grounds. (Clearly, familiarity is a much better argument.)nicely. That is why I propose to do the same here (and serious option). I know that Javascript is a poorly designed language, but on that very specific topic most people agree that was has been done at the time was pure genius. It removes the weird C/C++ object that have no expressible type, and simplify the situation. Additional benefice is that funName now behave the same in all situation, which is also a simplification of the situation.2. I have tried to add property appropriately in Phobos, in particular for ranges: struct SomeRange { property bool empty(); property ref T front(); void popFront(); } There's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap. I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax.If you ask me, I think property have been abused in range design. Many ranges properties really shouldn't be properties. Additionally, this kind of boilerplate can easily be written by efficient to write program in them, as the tooling to a great job for you. As I discussed with you, tooling appears slowly in D because the language itself is unstable, the specification have many quirks, and dmd is not reusable for the job. We can either make more quirks in order to make our life easier, or less quirks in order for tools to make our life easier. The first one have immediate return on investment, however, it is shortsighted IMO.3. Whatever we do going forward should be _simple_ but not _simplistic_. Right now it's easy to forget that we're all close to the subject. We have it in working memory (at least it's what I think about all the time) and any incremental complexity is an easy cost to absorb intellectually. But when we need to teach this to newcomers or even approach it again with a "cold cache", any undue complexity will be jarring.Everybody know how a variable behave. This is the most simple and straightforward way for a property to work.4. Whether we like it or not, backward compatibility is an issue. The parens or no parens aspect upon a function call is too ubiquitous to write off as an obscure circumstance. So I don't think the obscurity argument applies. Granted, there are several ways to approach the compatibility issue, all with their specific tradeoffs. All I'm saying is that careful considerations of compatibility must be integral to whatever we do about this.Whatever solution we choose, it will break stuff. We'd better think of a nice way to handle the transition than a way to not break code. Think that PHP went from value typed object to reference typed object between 4 and 5. This is a major breakage of a codebase that is much bigger than D's. I was made possible by a great release management. We'd better acknowledge that our release management sucks, and fix that, than fearing the consequences of it everywhere.
Jan 25 2013
26-Jan-2013 09:04, deadalnix пишет:On Friday, 25 January 2013 at 19:59:59 UTC, Andrei Alexandrescu wrote:Automated tooling is admitting a defeat if we talk about expressive languages. Java was designed with automatic code manipulation in mind and even with todays proliferation of generators it's a pain to work with. TL;DR code is written once and read many times. -- Dmitry Olshansky1. Syntactic and semantic implications of properties that return callable entitiesI don't understand why this is a special case in the first place. It should behave just like a variable of the same type, period.C has no methods so the syntax "object.method" does not apply to it. In C++, "object.method" is probably the oddest construct in the entire language: it returns a type that exists but has no name, is not expressible syntactically, is not first class (one can't assign "object.method" to a variable), and has only two allowed operations: take address or apply the function call operator "()". Various C++ implementations have extensions that fix this. Both Walter and I consider these serious lapses in language design. Two of the most accessible elements of syntax do things of considerably low interest and use. I hope I now clarified why I have a dim view of arguments that - implicitly or explicitly - assume the C or C++ behavior in this area is an example to follow on technical grounds. (Clearly, familiarity is a much better argument.)has been mentioned here, it sound like a serious option). I know that Javascript is a poorly designed language, but on that very specific topic most people agree that was has been done at the time was pure genius. It removes the weird C/C++ object that have no expressible type, and simplify the situation. Additional benefice is that funName now behave the same in all situation, which is also a simplification of the situation.2. I have tried to add property appropriately in Phobos, in particular for ranges: struct SomeRange { property bool empty(); property ref T front(); void popFront(); } There's more " property" to be seen with "save" and "back". Subjectively that just didn't work well for me. It adds clutter to an otherwise simple and straightforward API, and penalizes usage for benefits that I could never reap. I understand how some people are glad to put that in everywhere, and find meaning in requiring parens with popFront and popBack but not the others. Yet for me it was liberating (see 1 above too) I could just write "r.popFront" without the parens and have it do its deed. It is the right semantics for a simple syntax.If you ask me, I think property have been abused in range design. Many ranges properties really shouldn't be properties. Additionally, this kind of boilerplate can easily be written by to write program in them, as the tooling to a great job for you.
Jan 26 2013
On Saturday, 26 January 2013 at 08:29:40 UTC, Dmitry Olshansky wrote:Automated tooling is admitting a defeat if we talk about expressive languages. Java was designed with automatic code manipulation in mind and even with todays proliferation of generators it's a pain to work with. TL;DR code is written once and read many times.Using tooling is admitting defeat ? That is very misplaced pride (and not even an argument). And if you think that verbose code is less readable, think twice, or follow both links : http://code.jquery.com/jquery.js http://code.jquery.com/jquery.min.js No doubt the less verbose one is more readable !
Jan 26 2013
26-Jan-2013 12:57, deadalnix пишет:On Saturday, 26 January 2013 at 08:29:40 UTC, Dmitry Olshansky wrote:There is no pride. Requiring a separate tool to generate code even in simple cases is a defeat. Using tools is fine to refactor, navigate etc. but not to generate "boilerplate" as in the end it still has to be read, modified and fitted with the rest of code. Boilerplate generally has no place in code at all if we can help it.Automated tooling is admitting a defeat if we talk about expressive languages. Java was designed with automatic code manipulation in mind and even with todays proliferation of generators it's a pain to work with. TL;DR code is written once and read many times.Using tooling is admitting defeat ? That is very misplaced pride (and not even an argument).And if you think that verbose code is less readable, think twice, or follow both links : http://code.jquery.com/jquery.js http://code.jquery.com/jquery.min.js No doubt the less verbose one is more readable !Obfuscation/minification and boilerplate is not the same. And I bet the second example is the same exact code so you missed the point completely. -- Dmitry Olshansky
Jan 26 2013
On 01/24/2013 07:34 PM, Jesse Phillips wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has nothing to do with property. It has to do with defining what += /does/ to a property. I think that what you want is semantic property rewriting. See this: http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semanticrewritingofproperties1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value.As mentioned, this seems dangerous. I'd suggest requiring when there is ambiguity. It still has generic problems, but it will never be silent.4. No more property.I'm on the side that would miss optional parens if they died. In would be nice if property actually made a function behave like a field. foo += bar; It seems there are lots of complications around this? So yes kill property.On another note, To properly correct this situation we will break code. So before you get started be sure to try out the new feature preview release approach :)
Jan 24 2013
On Friday, January 25, 2013 10:37:51 kenji hara wrote:2013/1/25 kenji hara <k.hara.pg gmail.com>Honestly, I don't think that English grammar has anything to do with this. Code isn't English, even if the symbol names chosen are in English. A programming language's grammar should reflect what works best for having a language which is appropriately usable and maintainable. That doesn't necessarily have anything to do with the grammar of any natural language, especially when you consider how different programming language grammars are from those of natural languages. - Jonathan M DavisI have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attributeI think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses
Jan 24 2013
On 1/24/13 9:02 PM, Jonathan M Davis wrote:On Friday, January 25, 2013 10:37:51 kenji hara wrote:I agree parallels with natural language are tenuous. Anyhow, here's a thought. It is becoming rather clear that one way or another that optional parens are here to stay. So no more need to argue over that - it's just there. Once we consider this a given, the design space is much easier to navigate (which is what Kenji is doing). Andrei2013/1/25 kenji hara<k.hara.pg gmail.com>Honestly, I don't think that English grammar has anything to do with this. Code isn't English, even if the symbol names chosen are in English. A programming language's grammar should reflect what works best for having a language which is appropriately usable and maintainable. That doesn't necessarily have anything to do with the grammar of any natural language, especially when you consider how different programming language grammars are from those of natural languages.I have thought an additional idea. If we really want a feature to disable optional parentheses for normal functions, we can add function attribute to the language spec. int foo(); property int bar(); function int baz(); // new! int x1 = foo(); // ok int x2 = foo; // optional parentheses, allowed int y1 = bar(); // disallowed, calling int is meaningless int y2 = bar; // ok int z1 = baz(); // ok int z2 = baz; // *disallowed* by function attributeI think calling a function which does not annotated with attribute without parenthesis is legal, Even if a function has some side-effects and a name looks like verb. Because native English grammar does not require parentheses. He runs(). // normal function call He runs. // optional parentheses
Jan 24 2013
On 2013-01-25 03:19, Andrei Alexandrescu wrote:I agree parallels with natural language are tenuous.No, they're not. Perhaps in this particular case. But code is for humans to be able to read and write. That's why it looks similar to natural languages. Otherwise we would just program in machine code. The computer doesn't really care. -- /Jacob Carlborg
Jan 25 2013
On Friday, January 25, 2013 11:09:15 kenji hara wrote:That is more serious than (a). If we adopt this rule, we will *really* get lost the way to distinguish property functions and raw data fields. (Note that: In current typeof(foo) already returns int. So AddressExp is only one way to getting (normal|property) function information by its type.) From the view of meta-programming, I think this makes a serious flaw.We could add a __trait which detected whether a field was an actual variable or not. - Jonathan M Davis
Jan 24 2013
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>On Friday, January 25, 2013 11:09:15 kenji hara wrote:OK, let's think. When a property function exists: property int foo(); static assert(__traits(isProperty, foo) == true); Pros: We can get minimum information. Cons: We cannot check whether the foo is other function attributes: pure, nothrow, safe. static assert(__traits(getPropertyType, foo).stringof == " property int()"); Pros: We can access all information about property function. Cons: __traits() is parsed as an expression, so we cannot use it as a type directly. __traits(getPropertyType, foo)* fp; // declaring function pointer Instead, some template should be required. TypeTuple!(__traits(getPropertyType, foo))[0]* fp; auto fp = &foo; // Not allowed, because property function foo returns an rvalue. auto fp = cast(function)&foo; //New, Gets a function pointer of foo Pros1: Can access fully information of foo from typeof(fp). Pros2: We can call a property function indirectly through function pointer. Pros3: Newly syntax and semantics has no conflict with existings. Cons: cast(function) and cast(delegete) necessary. auto p = cast( property)&foo; // p is a function pointer. auto p = cast( property)&s.foo; // p is a delegate. Pros: Only one new syntax is necessary. Cons: Ugly... --- In the compile world of D, a function type is already a first class object to carry the information related function. Similarly, function pointer and delegate are widely used as a runtime container to make runtime bindings to function symbols.That is more serious than (a). If we adopt this rule, we will *really* get lost the way to distinguish property functions and raw data fields. (Note that: In current typeof(foo) already returns int. So AddressExp is only one way to getting (normal|property) function information by its type.) From the view of meta-programming, I think this makes a seriousflaw. We could add a __trait which detected whether a field was an actual variable or not.From these facts, creating an escape hatch from property function to normalfunction type/pointer is enough worthwhile to me. It makes it possible to reuse a number of meta-programming operations for normal function/function type/function pointers. overloaded functions by CastExpression. void foo() {} void foo(int) {} auto fp = cast(void function())&foo; // fp is equal to the address of first foo. So, I prefer adding newly meanings to CastExp. Kenji Hara
Jan 24 2013
On Friday, January 25, 2013 13:47:31 kenji hara wrote:2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>I know, and I agree with it. But Andrei is pushing for removing property entirely and looking for arguments to keep it. And IMHO, the issue of how setters are handled is an extremely good reason to keep property. - Jonathan M DavisAnd actually, something far more important than any of those reasons is the issue of setters. We've focused most of this discussion on optional parens and the situation with getter properties, but setter properties and their issues are also important. Would you want code like this to compile? range.popFront = 17; container.linearRemove = range; path.baseName = ".xyz"; str.icmp = "hello"; enforce(a == b) = "msg"; arr.sameHead = arr2; With property, we can restrict the functions which can be used with the setter syntax to functions where that makes sense. Without it, all kinds of ridiculous code like the code above would be allowed. Allowing optional parens is one thing, but conflating that with properties is something else entirely. Property functions are not just functions which are called without parens, and we shouldn't act like they are.
Jan 24 2013
2013/1/25 Jonathan M Davis <jmdavisProg gmx.com>I know, and I agree with it. But Andrei is pushing for removing property entirely and looking for arguments to keep it. And IMHO, the issue of how setters are handled is an extremely good reason to keep property.I'd like to argue that we should keep property attribute. Kenji Hara
Jan 24 2013
OK, it has become difficult to follow all thread (newsgroups are not that perfect for this), so I will do "tl; dr" in a form of I final proposal. Basic statement 1: Breaking user code is inevitable Basic statement 2: Special cases are indicators something wrong is with design Basic statement 3: Data is not function. Function is not data. (Sorry, John von Neumann!) Property is data. Proposal itself: *) -property flag becomes no-op *) parens for all callables are mandatory *) parens for properties are prohibited *) properties are always treated to be of type of their return data *) As a consequence - in UFCS property always behaves as a parameter, never as function Transition issues: *) Before merging new behavior to master, staging is created from last backwards-compatible. Official announcement is made that it will be bug-fix supported for at least 6 months. *) Meta bugzilla issue is created to make Phobos code more strict in this regard. Release with new behavior will be allowed to go to staging only after this issue is taken care of. *) All property-related issues that ensure data-like behavior like "+=" are marked as preapproved. And yes, I know that Andrei has already made his decision about optional parens and this is also a no-op. But oh well.
Jan 25 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote: One more thing (see also this: http://www.25hoursaday.com/CsharpVsJava.html#properties) In order to avoid properties throwing exceptions, maybe is wise to impose getters and setters to be nothrow. try{ myClock.Hours = 28; /* setter throws exception because 28 is an invalid hour value */ myClock.Minutes = 15; myClock.Seconds = 39; }catch(InvalidTimeValueException itve){ /* figure out which field was invalid and report error */ }
Jan 25 2013
On 2013-37-25 17:01, eles <eles eles.com> wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote: One more thing (see also this: http://www.25hoursaday.com/CsharpVsJava.html#properties) In order to avoid properties throwing exceptions, maybe is wise to impose getters and setters to be nothrow. try{ myClock.Hours = 28; /* setter throws exception because 28 is an invalid hour value */ myClock.Minutes = 15; myClock.Seconds = 39; }catch(InvalidTimeValueException itve){ /* figure out which field was invalid and report error */ }But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though. -- Simen
Jan 25 2013
On Friday, 25 January 2013 at 16:48:21 UTC, Simen Kjaeraas wrote:On 2013-37-25 17:01, eles <eles eles.com> wrote:See this answer here: http://forum.dlang.org/post/mdhvjbjqryzjljzqleay forum.dlang.org The problem is that programmers would start feeling like "it's better" to check every assignment for exceptions, in the case that the variable is latter converted into a throwing property. I have no solution to that, though... OOH, I feel it will lead to bad programming style. OTOH, I feel like masking a database interrogation behind a property will throw some exception sooner or later. So, I am clueless.On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though.
Jan 25 2013
On Friday, 25 January 2013 at 19:50:23 UTC, eles wrote:On Friday, 25 January 2013 at 16:48:21 UTC, Simen Kjaeraas wrote:You can easily wrap all of your functions in a try catch block that will act as a safety net and catch all potential Exception throws. Unfortunately I don't know if there's a performance hit with wrapping up all functions in this way. --rtOn 2013-37-25 17:01, eles <eles eles.com> wrote:See this answer here: http://forum.dlang.org/post/mdhvjbjqryzjljzqleay forum.dlang.org The problem is that programmers would start feeling like "it's better" to check every assignment for exceptions, in the case that the variable is latter converted into a throwing property. I have no solution to that, though... OOH, I feel it will lead to bad programming style. OTOH, I feel like masking a database interrogation behind a property will throw some exception sooner or later. So, I am clueless.On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:But setting the hours field to 28 is natural? While I want all properties to be safe nothrow pure, it is unlikely to be a good idea to force this upon people. I'm all for putting it in the style guide, though.
Jan 25 2013
On Friday, January 25, 2013 17:37:48 eles wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote: One more thing (see also this: http://www.25hoursaday.com/CsharpVsJava.html#properties) In order to avoid properties throwing exceptions, maybe is wise to impose getters and setters to be nothrow. try{ myClock.Hours = 28; /* setter throws exception because 28 is an invalid hour value */ myClock.Minutes = 15; myClock.Seconds = 39; }catch(InvalidTimeValueException itve){ /* figure out which field was invalid and report error */ }And why wouldn't setters be able to throw. Why on earth would you do other than throw in code like you have above? How on earth would a setter report a bad argument if it was forced to be nothrow? Exceptions are the correct solution. Setters _need_ to be able to throw. Plenty of them don't need to, but plenty of them do. For instance, many of the properties in std.datetime will throw if you give them invalid values (like setting the hour to 28). I don't see how you could possibly argue that a setter should not be able to throw. - Jonathan M Davis
Jan 25 2013
On Friday, 25 January 2013 at 19:30:41 UTC, Jonathan M Davis wrote:On Friday, January 25, 2013 17:37:48 eles wrote:You are right. In fact, just after I post the message, I was hit by second toughts. But a issue still remains: assignments of variables are not usually checked for exceptions. Programmers do not have in mind that they could trigger exceptions. However, properties could do. The danger that I see is that programmers will start to "preventively" check everything for exceptions, "just in case" that those current variable assignments would be latter turned into properties. Do you feel like embracing all your code in try/catch?On Thursday, 24 January 2013 at 08:35:01 UTC, Walter BrightAnd why wouldn't setters be able to throw. Why on earth would you do other than throw in code like you have above? How on earth would a setter report a bad argument if it was forced to be nothrow? Exceptions are the correct solution. Setters _need_ to be able to throw. Plenty of them don't need to, but plenty of them do. For instance, many of the properties in std.datetime will throw if you give them invalid values (like setting the hour to 28). I don't see how you could possibly argue that a setter should not be able to throw.
Jan 25 2013
On Friday, January 25, 2013 20:41:01 eles wrote:You are right. In fact, just after I post the message, I was hit by second toughts. But a issue still remains: assignments of variables are not usually checked for exceptions. Programmers do not have in mind that they could trigger exceptions. However, properties could do. The danger that I see is that programmers will start to "preventively" check everything for exceptions, "just in case" that those current variable assignments would be latter turned into properties. Do you feel like embracing all your code in try/catch?Except that variable assignments _can_ throw, because opAssign could throw. It's true that replacing a variable with a property function which checks its arguments would likely add a new exception to catch, but there's really no way around that. But if the property function checks for stuff which was supposed to be valid before, you changed the semantics anyway, which could be done in a variety of other ways (e.g. making the property function multiply the argument by 7). The reality of the matter is that a property function _isn't_ a variable, just like an overloaded operator isn't the same as using that operator on a built-in type. And the issues are pretty much the same as they are with overloaded operators. But what should be done with try-catch blocks depends on what the code's doing, and if you're having to litter your code with them, you're probably doing something wrong anyway. Still, the possible breakage caused by replacing a variable with a property function which throws is the sort of thing that needs to be considered when making that change. - Jonathan m Davis
Jan 25 2013
On 2013-01-25 17:37, eles wrote:One more thing (see also this: http://www.25hoursaday.com/CsharpVsJava.html#properties) In order to avoid properties throwing exceptions, maybe is wise to impose getters and setters to be nothrow. try{ myClock.Hours = 28; /* setter throws exception because 28 is an invalid hour value */ myClock.Minutes = 15; myClock.Seconds = 39; }catch(InvalidTimeValueException itve){ /* figure out which field was invalid and report error */ }One of the points of properties is to have a field with validation. To indicate the validation failed you would throw an exception. Therefore properties need to be able to throw exceptions. -- /Jacob Carlborg
Jan 26 2013
On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T -- What are you when you run out of Monet? Baroque.
Jan 25 2013
On Friday, 25 January 2013 at 18:41:46 UTC, H. S. Teoh wrote:...Sound base that avoid discussion of controversial topics :) Looks like I can agree with almost everything. Probably even everything. Only thing that needs to be defined is property on free-functions: disallow, treat as global variable or treat as an extension methods. We has small discussion on this topic with deadalanix afair somewhere up the topic.
Jan 25 2013
On Friday, January 25, 2013 19:51:53 mist wrote:On Friday, 25 January 2013 at 18:41:46 UTC, H. S. Teoh wrote:So, you're arguing that property shouldn't be usable on anything but member functions? We've had discussions on that in the past, and most everyone agreed that it should be legal to use property on module-level variables, and I've never heard anyone try to argue before that it shouldn't work with UFCS (which is what I assume you mean by extension methods - I don't know what else you would mean). There's an ambiguity problem that needs to be solved with free functions where in some cases, you can't properly distinguish between whether it's supposed to be a getter or a setter, but that can be fixed (e.g. property(get) and property(set)), but I think that if you're going to argue that something like bool exists(string filename) {...} if(filename.exists) or S globalVar() {...} if(globalVar == blah) shouldn't work, then you're fighting a losing battle. An both of those idioms are used in Phobos. I agree that calling it a property is a little silly when it's a module-level variable, since there's no object for it to be a property of, but really, property is an abstraction for variables in general, not just member variables. - Jonathan M Davis...Sound base that avoid discussion of controversial topics :) Looks like I can agree with almost everything. Probably even everything. Only thing that needs to be defined is property on free-functions: disallow, treat as global variable or treat as an extension methods. We has small discussion on this topic with deadalanix afair somewhere up the topic.
Jan 25 2013
On Friday, 25 January 2013 at 19:30:26 UTC, Jonathan M Davis wrote:...I am not going to argue anything, I am just asking _how_ they are supposed to work, what are exact semantic. I have added various syntax cases to wiki: What I am going to argue is if all of those example are supposed to work. We can't define property semantics to be "just like data" when property symbol can't be just interchanged with data symbol. From the syntax point of view no issues there.
Jan 25 2013
On Fri, Jan 25, 2013 at 08:46:51PM +0100, mist wrote:On Friday, 25 January 2013 at 19:30:26 UTC, Jonathan M Davis wrote:...I am not going to argue anything, I am just asking _how_ they are supposed to work, what are exact semantic. I have added various syntax cases to wiki: What I am going to argue is if all of those example are supposed to work. We can't define property semantics to be "just like data" when property symbol can't be just interchanged with data symbol. From the syntax point of view no issues there.From my stance that property should make the function behave like avariable, all of the examples in the above link can be resolved thus:struct Type { property void native(int); }This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }property void external1(int); // valid? (no assignment context)Valid, this is equivalent to defining a module-level variable: int external1;property void external2(Type, int); // valid? (extra parameter comparing to typical setter)Valid, because UFCS lets you use it as though it were a member variable of Type.void main() { Type t; t.native = 42; // typical external1 = 42; // allowed or not?Allowed, because external1 behaves like a module-level variable.42.external1; // allowed or not?Not allowed, because the following isn't allowed either: int x; void main() { 1.x; // Error: nonsensical syntax } IOW, property functions must be treated as variables externally, NOT as normal functions.t.external2 = 42; // allowed or not? }Allowed, because external2, via UFCS, behaves as though it were a member variable of Type. All of the confusing/unclear/ambiguous cases come from an incomplete implementation of property and an unnecessary conflation with normal functions. A property function should not be treated like a normal function. It turns the function into a variable-like entity that *no longer acts like a function to the outsider*. Neither should normal functions for whatever strange reasoning be conflated with property functions, because functions are not variables. It's actually very straightforward once you remove all the unnecessary conflations, and disregard, for the time being, the problems in the current implementation. T -- There is no gravity. The earth sucks.
Jan 25 2013
Am Fri, 25 Jan 2013 12:12:55 -0800 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:Only if the getter is marked as const. We can discuss if that should be required, but in the code above, native isn't necessarily const.struct Type { property void native(int); }This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }All of the confusing/unclear/ambiguous cases come from an incomplete implementation of property and an unnecessary conflation with normal functions. A property function should not be treated like a normal function. It turns the function into a variable-like entity that *no longer acts like a function to the outsider*. Neither should normal functions for whatever strange reasoning be conflated with property functions, because functions are not variables.Please add you proposed changes to Proposal 1 in this wiki page or add another proposal to it: http://wiki.dlang.org/Property_Discussion_Wrap-up
Jan 25 2013
Am Fri, 25 Jan 2013 21:28:34 +0100 schrieb Johannes Pfau <nospam example.com>:Am Fri, 25 Jan 2013 12:12:55 -0800 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:Ah you fooled me! There is only a setter in the first example!Only if the getter is marked as const. We can discuss if that should be required, but in the code above, native isn't necessarily const.struct Type { property void native(int); }This should behave as though you wrote this: struct Type { // const because there is no setter const int native; }
Jan 25 2013
On Fri, 25 Jan 2013 10:39:50 -0800, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:++ -- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T
Jan 25 2013
Am Fri, 25 Jan 2013 10:39:50 -0800 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:- It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense.3 or more arguments. UFCS properties have 2 arguments: property void age(Person p, int value); //OK, bad example, but you get the idea
Jan 25 2013
On Fri, Jan 25, 2013 at 09:06:44PM +0100, Johannes Pfau wrote:Am Fri, 25 Jan 2013 10:39:50 -0800 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:[...] Good point, so it's 2 or more arguments for member functions, and 3 or more for module-level functions. Another thing I forgot to mention: once a function has been declared property, you cannot call it like a normal function anymore. So if you declare at the module level: property void age(Person p, int value); then: void main() { Person p; //age(p, 123); // Error: cannot call age like a normal function //p.age(123); // ditto p.age = 123; // OK } The second case (p.age(123)) is valid only if age() returns a delegate. Again, property turns the function into a variable-like entity that does not behave like a normal function to the outside world. T -- Lottery: tax on the stupid. -- Slashdotter- It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense.3 or more arguments. UFCS properties have 2 arguments: property void age(Person p, int value); //OK, bad example, but you get the idea
Jan 25 2013
25-Jan-2013 22:39, H. S. Teoh пишет:On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:Good summary of what property should do. Let's just not forget that works like plain variable must clearly tackle contexts such as: a.b.c.d = xyz; //where b, c, d are properties And things like: a.prop += qwerty; I can see how it must work from your proposal but listing some "canonical" re-writes won't hurt. -- Dmitry OlshanskyThis has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.I've refrained so far from participating in this thread, but maybe it's time to say something. 1) property and optional parentheses are orthogonal issues. Let's not conflate them and cause more unnecessary confusion in what is already a complex and convoluted discussion. 2) Personally, I don't like leaving out parentheses, but I don't really care either way. In any case, this has nothing to do with property. 3) So, as far as property is concerned, let's forget about optional parentheses or not. 3) property is necessary for good abstraction. Yes, there have been precedents of abuse (like .dup and .idup, which really should *not* be properties but methods), and there are problems in the current implementation of property, but the _concept_ of property itself is a sound one. People have already mentioned the use case of a member variable that needs to be replaced with a getter/setter method. Conceptually speaking, the user of the class should not need to know or care whether it's just a POD field or an abstract entity manipulated by property functions. For example, an Array class has a .length property, and user code should not need to know nor care if this length is an actual size_t field, or something else. All it needs to know is you can get a size_t out of it, and (optionally) change its value (if it's non-const, or if there's a setter method). Sometimes, you get into the situation where it's *possible* to implement a property as a plain old field, but not desirable because of the SSOT (single source of truth) principle. It could be a computed value based on implementation-specific parameters, for example. It would not be nice if you had to store its value, then change code everywhere to make sure that it's always updated when the underlying parameters change. Lots of ugly, unnecessary, inefficient, and fragile code. Therefore, property is necessary. If it causes a problem with the syntax, well, that's a problem with the syntax, not with the concept of property itself. As far as syntax is concerned, it should be very straightforward. Given that the goal of property is to simulate a variable, it should syntactically be identical to a variable, regardless of what it returns. So, given: struct S { property T prop() { ... } } S s; Then: a) Writing s.prop returns a value of type T, for any type T (POD or struct or class or delegate or whatever); b) Writing s.prop() invokes opCall on the *return value* (because .prop behaves exactly as though it were an actual field); c) As a corollary, if T is not callable, then s.prop() is illegal; d) &s.prop returns a pointer to T (if .prop returns a ref). e) As for taking the address of the .prop function itself, my take on it is that (i) from a user's POV, .prop should be indistinguishable from a plain old field, so you shouldn't ever need to do this, and therefore (ii) it's impossible, and (iii) if you *really* need to do it, do this instead: struct S { property T prop() { return this.propImpl(); } // You really only need to know about propImpl if you're // inside S's implementation anyway, so this is private. private T propImpl() { ... } void someMethod() { auto ptr = &propImpl; // There, now you have it. } } f) IOW, .prop cannot be distinguished from an actual field under normal circumstances. If you *really* need to do this (e.g. in serialization code), then use __traits. Consequently: - Assignment syntax like f=g should NOT be treated equivalently to f(g) because conceptually it makes no sense. Writing writeln = "abc"; makes no sense because writeln is not a value that you write to. Writing s.prop = "abc" *does* make sense, because S.prop is a property, and therefore behaves like a variable. Writeln is a function, not a property, so this is illegal. - Syntax like s.prop++ should work automatically (equivalent to s.prop(s.prop+1)), if .prop has both a getter and setter property. It should NOT be allowed for arbitrary methods m just because m has both overloads of m() and m(T). - It's illegal to mark a function that takes 2 or more arguments as property, because it makes no sense. The bottom line is, if you mark a function as property, then it should behave as if it were a variable of its return type. This has nothing to do with optional parentheses or not, and assignment syntax should be reserved for variables (and by extension property, because property means something behaves like a variable), not arbitrary functions. T
Jan 25 2013
On Friday, January 25, 2013 10:39:50 H. S. Teoh wrote:I've refrained so far from participating in this thread, but maybe it's time to say something.[snip] I agree with pretty much everything that you said, and it's exactly why we need explicit properties. So, we need to keep property and make whatever adjustments are necessary in order to make it function like a variable would to the point that you can swap out variables and property functions without breaking code (though that will probably mean allowing something like marking variables with property to make them be treated as rvalues rather than just improving the handling of property functions). - Jonathan M Davis
Jan 25 2013
On Friday, January 25, 2013 10:39:50 H. S. Teoh wrote:I've refrained so far from participating in this thread, but maybe it's time to say something.[snip] Another issue that you didn't mention (and which hasn't come up in this particular discussion, I don't believe) is what to do about disambiguating property functions that conflict. You can't use the full import path for a function when using the property syntax, so there's not currently a way to disambiguate property functions which conflict. So, we'll need to find a solution for that. - Jonathan M Davis
Jan 25 2013
Here are my two cents: First, about optional parentheses: Optional parentheses = ambiguity. int foo() { return 4; } auto x = foo; // gives 4 or gives function foo? It seems to me any ambiguity should be an error. However… it only matters when the type system can't provide the missing detail, as above. The ambiguity may be resolved either in the function signature or at the call site. property partly helps resolve it at the function signature, but it is a different issue from optional parentheses. Ambiguity can also be resolved at the call site instead of the function signature. It needs to be as clear and concise as possible in addition to being unambiguous. D's method of disambiguating cases often uses the keyword "cast". Applying it in this case would lead to "cast(function)" or "cast(delegate)" to indicate the function and not the return value, where the default is to indicate the return value. int foo() { return 4; } int function() goo() { return foo; } auto doh = foo(); // gives 4 auto go = foo; // Error: can't deduce type of expression foo auto fun = cast(function) foo; // gives foo auto ae = goo; // Error: can't deduce type (either goo or function int() foo ) auto fe = goo(); // Error: can't deduce type (either foo or 4) auto ga = goo()(); // gives 4 auto gu = cast(function) (goo()); // gives foo auto gi = cast(function) goo; // gives goo This solution is unambiguous and clear, but unfortunately not very concise. In fact, "cast(function) foo" is rather a long way of saying "&foo", but much clearer and possibly safer. The type system can probably resolve most of these ambiguities anyway, which would mean the cast wouldn't appear very often, but I'm not sure. I have no real opinion about property. Ideally the compiler could deduce what is and isn't a property without the ugly property attached to all the signatures, but it might invite so many abuses of this process that it's not worth it.
Jan 25 2013
On 01/25/2013 10:44 PM, Zach the Mystic wrote:Here are my two cents: First, about optional parentheses: Optional parentheses = ambiguity. ...No, you can definitely have ambiguity without optional parentheses. Unless that is supposed to be a destructive update. Is your statement ambiguous?int foo() { return 4; } auto x = foo; // gives 4 or gives function foo? It seems to me any ambiguity should be an error. However… it only matters when the type system can't provide the missing detail, as above. ...That is not ambiguous.
Jan 25 2013
On Friday, 25 January 2013 at 22:02:06 UTC, Timon Gehr wrote:On 01/25/2013 10:44 PM, Zach the Mystic wrote:Actually, you're right. I meant: Optional parentheses as a feature leads to ambiguity precisely when they are not used.Here are my two cents: First, about optional parentheses: Optional parentheses = ambiguity. ...No, you can definitely have ambiguity without optional parentheses. Unless that is supposed to be a destructive update. Is your statement ambiguous?But this time *your* comment is ambiguous! If you mean my *statement* is not ambiguous, then yes.int foo() { return 4; } auto x = foo; // gives 4 or gives function foo? It seems to me any ambiguity should be an error. However… it only matters when the type system can't provide the missing detail, as above. ...That is not ambiguous.
Jan 25 2013
On Saturday, 26 January 2013 at 00:47:38 UTC, Zach the Mystic wrote:Actually, that's ambiguous too. My English language statement.That is not ambiguous.But this time *your* comment is ambiguous! If you mean my *statement* is not ambiguous, then yes.
Jan 25 2013
On Friday, 25 January 2013 at 21:44:28 UTC, Zach the Mystic wrote:Here are my two cents: First, about optional parentheses: Optional parentheses = ambiguity. int foo() { return 4; } auto x = foo; // gives 4 or gives function foo?\4, we are talking about D not C.
Jan 25 2013
On 24.1.2013 9:34, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.Maybe one possible issue to note. I am sorry if someone already noted this but I didn't saw it so here it is. In druntime's object_.d AssociativeArray has: property size_t length() { return _aaLen(p); } By removing property typeof([].length) is no longer uint or ulong. It would change into uint() or ulong(). And not just for length, but any other properties type's would change. I think that this is one big possible code breaker for everyone that uses something similar to the following: typeof([].length) l = [].length; Maybe I am wrong but my personal opinion is that code like this should compile because semantically length is a property and the fact that it is a functions is just a implementation detail.
Jan 26 2013
I was just working on some work code and noticed this line that I wrote a while ago: public property string userId(string file = __FILE__, size_t line = __LINE__) { That's a getter, I always use it "getUser(userId);" etc..... but it "takes" two arguments. If we require getters to have zero arguments, it will break this, and that will annoy me. We need to be careful about arbitrarily deciding something doesn't make sense and restricting it when there's no real technical reason for it. (Wondering why I did this? If you aren't logged in, this throws a Not Logged In Exception. The file and line are passed to the exception constructor, meaning then the error message will tell me exactly where I forgot the nicer login check. After wasting cumulative hours on similar problems in earlier iterations, I put this in there to eliminate that time sink.)
Jan 27 2013
On Monday, January 28, 2013 00:18:15 Adam D. Ruppe wrote:I was just working on some work code and noticed this line that I wrote a while ago: public property string userId(string file = __FILE__, size_t line = __LINE__) { That's a getter, I always use it "getUser(userId);" etc..... but it "takes" two arguments. If we require getters to have zero arguments, it will break this, and that will annoy me. We need to be careful about arbitrarily deciding something doesn't make sense and restricting it when there's no real technical reason for it. (Wondering why I did this? If you aren't logged in, this throws a Not Logged In Exception. The file and line are passed to the exception constructor, meaning then the error message will tell me exactly where I forgot the nicer login check. After wasting cumulative hours on similar problems in earlier iterations, I put this in there to eliminate that time sink.)I think that one of two things would be likely to happen were property to stay and properly enforce that it be called with no parens: 1. Your function would be illegal because it had too many arguments. 2. It would be legal, but you could never call it with any arguments for file or line except the defaults, because there would be no syntactic way to do so. But then again, if all you want is a getter and not a setter, and we allow optional parens to continue (which appears to be the case), then you wouldn't have to declare it as property to get the syntax that you want. It just wouldn't be possible to guarantee that you could swap it out for a variable later without breaking code, since it would be possible for someone to call it with parens. - Jonathan M Davis
Jan 27 2013
On Thu, 24 Jan 2013 03:34:42 -0500, Walter Bright <newshound2 digitalmars.com> wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules. 1. Empty parens are optional. If there is an ambiguity with the return value taking (), the () go on the return value. 2. the: f = g rewrite to: f(g) only happens if f is a function that only has overloads for () and (one argument). No variadics. 3. Parens are required for calling delegates or function pointers. 4. No more property.Disagree. property serves a very good purpose -- specifying intent. If the intention of a function is to be used as a dynamic field, use property, otherwise do not. Whether or not parentheses should be required on non- property functions, I've given up that struggle. It's not too terrible, and the benefits are difficult to argue against. But please, please, PLEASE do not let normal functions be called as setters. If we get rid of property, we are back to this. Your simple requirements will leave too many functions open to abuse. When you take away property, you take away the expression power of an API designer. I contend that the issue with property was that it was half-implemented. When a half-implemented feature is used for 4 years, it leads to confusion when it doesn't work as specified. In other words, we asked you to build a fence. You built one, but didn't finish it, left a gaping hole. Then you complain about how the fence was useless. I would be satisfied with Kenji's implementation. As I understand it: property on a getter would mean implicit calling of the function. property on a setter would mean calling x = y as x(y). property functions could not be called like normal functions. Parentheses are optional on normal no-arg functions when used as getters. Normal single arg or variadic functions are NOT ALLOWED to be used as setters. Do it. I think 99% of the people here would be OK with this. -Steve
Jan 27 2013
On Mon, Jan 28, 2013 at 12:22:01AM -0500, Steven Schveighoffer wrote: [...]Disagree. property serves a very good purpose -- specifying intent. If the intention of a function is to be used as a dynamic field, use property, otherwise do not. Whether or not parentheses should be required on non- property functions, I've given up that struggle. It's not too terrible, and the benefits are difficult to argue against. But please, please, PLEASE do not let normal functions be called as setters. If we get rid of property, we are back to this. Your simple requirements will leave too many functions open to abuse. When you take away property, you take away the expression power of an API designer. I contend that the issue with property was that it was half-implemented. When a half-implemented feature is used for 4 years, it leads to confusion when it doesn't work as specified. In other words, we asked you to build a fence. You built one, but didn't finish it, left a gaping hole. Then you complain about how the fence was useless. I would be satisfied with Kenji's implementation. As I understand it: property on a getter would mean implicit calling of the function. property on a setter would mean calling x = y as x(y). property functions could not be called like normal functions. Parentheses are optional on normal no-arg functions when used as getters. Normal single arg or variadic functions are NOT ALLOWED to be used as setters. Do it. I think 99% of the people here would be OK with this.[...] +1. T -- May you live all the days of your life. -- Jonathan Swift
Jan 27 2013
On 01/28/2013 06:22 AM, Steven Schveighoffer wrote:... I would be satisfied with Kenji's implementation. As I understand it: property on a getter would mean implicit calling of the function. property on a setter would mean calling x = y as x(y). property functions could not be called like normal functions. Parentheses are optional on normal no-arg functions when used as getters. Normal single arg or variadic functions are NOT ALLOWED to be used as setters. ...This proposal unfortunately does not work too well because of UFCS.
Jan 28 2013
On Mon, 28 Jan 2013 11:31:33 -0500, Timon Gehr <timon.gehr gmx.ch> wrote:On 01/28/2013 06:22 AM, Steven Schveighoffer wrote:As many have stated in the past, UFCS getter properties can annotate their "this" argument: property void by5(this int x) { return x * 5;} by5 = 1; // error Another possibility is to only define property for setters. This is something I've come to realize that if we are simply going to allow omittable parens on getters, there is no functional value to property on them except for the rare case of a delegate property. That was always one of those things where I think too much emphasis was on that as a reason for property existence, it's very rare. -Steve... I would be satisfied with Kenji's implementation. As I understand it: property on a getter would mean implicit calling of the function. property on a setter would mean calling x = y as x(y). property functions could not be called like normal functions. Parentheses are optional on normal no-arg functions when used as getters. Normal single arg or variadic functions are NOT ALLOWED to be used as setters. ...This proposal unfortunately does not work too well because of UFCS.
Jan 28 2013
On 2013-01-28 18:07, Steven Schveighoffer wrote:Another possibility is to only define property for setters. This is something I've come to realize that if we are simply going to allow omittable parens on getters, there is no functional value to property on them except for the rare case of a delegate property. That was always one of those things where I think too much emphasis was on that as a reason for property existence, it's very rare.I think property adds clarity and shows intent. For example, now that we have UDA's I have create a struct called "attribute" which I use as an attribute for other structs to should be attributes: struct attribute {} attribute struct foo {} foo int a; Here attribute shows the intent. This is also why I like to have explicit interfaces and abstract classes compared with C++ which doesn't not. -- /Jacob Carlborg
Jan 28 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.Progressively, I start considering this as a not-so-bad idea. Anyway, the issue of property should be cleared up. The current state of affairs is poisoning the language.
Jul 19 2013
To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff.
Aug 10 2013
On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote:To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff.I like this. It is something like in Ruby. And Ruby also has some meta programming support and there are these 3 "templates" attr_reader, attr_writer and attr_accessor (both of the previous together). And one could write (in Ruby): class Foo attr_writer :name, :number #Ruby has symbols(something like enums) end And translates to: class Foo def name=(name) name = name //the name means class private variable in Ruby end def number=(number) number = number //and they don't need to be declared(dynamicly typed lang) end end So in D those 3 attr 'shortcuts' could be implemented with mixin templates. And instead of those 'symbols' they could be just a list of strings. Example: class Foo { mixin Reader!("name", "number"); } And something similar to happen. Although this not solves all property problems it makes writing them shorter. And I have started experimenting with that and it is almost finished, but it is a little different from what I described above. The file is a part of a thing I started working on in D, but here is a direct link(https://github.com/nikibobi/spine-d/blob/master/src/spine/util/property.d) and the files is isolated from the other things. See the unittests for examples.
Aug 10 2013
On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote:To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff.The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A {
Aug 10 2013
On Saturday, 10 August 2013 at 17:48:34 UTC, BLM768 wrote:On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote:Sorry; message got cut off when I tried to insert a tab and then pressed space with the "Send" button focused. Continuing... class A { property int foo(); property void foo=(int a); //etc. } However, it doesn't offer any significant advantage over the current property syntax other than providing a clearer distinction between getters and setters, which is only important when dealing with UFCS, as pointed out in an earlier post.To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff.The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A {
Aug 10 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.Here is my mindless proposal after reading some of the posts. 1. Properties are data. Cannot be called with parenthesis, unless it returns a delegate, in which case the delegate is called. The address of a property is invalid(possibly gotten through a trait). 2. Properties cannot be used in UFCS calls, unless they return a delegate. Only UFCS chaining allows for parenthesis-less calls. e.g., (). -> . why should D? From the little reading, the best I can tell is that the issue comes directly from UFCS and trying to avoid using parenthesis. Conflating the issue between properties and UFCS isn't an issue with properties or UFCS but with distinguishing between them. UFCS wants property like behavior but then that causes problems with properties themselves. Properties want function call behavior but then that makes them look like functions, yet this defeats the purpose of a property. Alternative, use a different syntax for chaining UFCS's. Instead of using ()., use something like func1:func2:func3:func4; where : seems to be a somewhat unused symbol... ~, >, >>, or others could potentially be used. Such a symbol AUTOMATICALLY is replaced with `().` since everything is a function call. (no properties can exist in the chain unless they return delegates, in which case the delegate is uses)
Aug 10 2013
On 10 August 2013 13:27, JS <js.mdnq gmail.com> wrote:On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:Might be wrong "cause I've only spent 5 minutes looking at it severall -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';This has turned into a monster. We've taken 2 or 3 wrong turns somewhere. Perhaps we should revert to a simple set of rules.Here is my mindless proposal after reading some of the posts. 1. Properties are data. Cannot be called with parenthesis, unless it returns a delegate, in which case the delegate is called. The address of a property is invalid(possibly gotten through a trait). 2. Properties cannot be used in UFCS calls, unless they return a delegate. Only UFCS chaining allows for parenthesis-less calls. e.g., (). -> . D? From the little reading, the best I can tell is that the issue comes directly from UFCS and trying to avoid using parenthesis.
Aug 10 2013
On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:This has turned into a monster. We've taken 2 or 3 wrong turns somewhere.My 2 cents on this, very late in the day. Sorry for the essay, hopefully it'll be worth your time. No fancy new ideas, but I *think* I have a nice solution that keeps everyone happy and avoids nasty corner-cases and ambiguities: 1) non-property functions must be called with parenthesis, *except* on UFCS calls. No assignment call syntax for non-properties. fun1.fun2; //illegal fun1.fun2(); //illegal fun1().fun2; //OK fun1().fun2(); //OK fun1; //illegal fun1(); //OK fun2 = var; //not a function call, but a normal assignment where //possible, e.g. initialising a function pointer. iota(100).map!"a+1".filter!"a%5".writeln; //LEGAL :-) Alternative way of saying it: optional paren for single argument calls in UFCS, enforced parenthesis elsewhere. Reason: No one wants writeln = "Hello World!"; but a lot of people want "Hello World!".writeln; Also, this removes visual ambiguity between the name of a function and it's result. That only really matters with alias/variadic template parameters but it is very annoying there. That will never conflict with UFCS so everyone's happy. Note that in the first two examples, fun1 is *NOT* a UFCS call and therefore cannot be done without parens. Preventing optional parens on non-UFCS stops any possible mixing of optional parenthesis and the unary & operator. 2) property enforces parenthesis-less calling for getters and assignment syntax for setters. No properties with more than one argument allowed. If a property returns a callable, any parenthesis will be applied to the callable Reason: Properties are not for general purpose work. The whole point of them is to be used roughly like variables and this is as close to that as we're gonna get. 3) Getting the address of a function is done with the & operator. Callables must always have parenthesis *except* when: Parenthesis would be optional for an equivalent normal function AND not when the callable is the result of an expression: 42.aDelegate.foo; //OK 42.returnsADelegate.foo; //OK, foo acts on the delegate 42.returnsADelegate().foo; //OK, foo acts on the delegate 42.returnsADelegate()().foo; //OK, foo acts on //the return value of the delegate aDelegate; //illegal aDelegate() //OK "blah".aDelegate; //OK "blah".aDelegate(); //OK auto a = &returnsADelegate; //a is function pointer to //returnsADelegate a; //illegal auto b = a(); //OK, calls a and b is a delegate b; //illegal b(); //OK, calls the delegate. //given some struct Bar that overloads opBinary!"+" and opCall Bar x,y; x; //illegal x(); //opCall (x+y) //does not call opCall (x+y)() //does call opCall Reason: This allows them to be used transparently like normal functions where possible, but removes ambiguity elsewhere. 3a) Explicitly taking the address of a property. Attempting to shoe-horn this in with normal syntax causes hell for the rest. I suggest some magic here, e.g. __traits(propertyGetterAddress, a.prop) and __traits(propertySetterAddress, a.prop) A function pointer to a property must be called as a normal function pointer. auto v = __traits(propertyGetterAddress, a.prop); auto n = v; //n is a function pointer to the getter a.prop, //same as v auto n = v(); //n is equal to the return of the getter a.prop auto h = __traits(propertySetterAddress, a.prop); auto j = h; //j is a function pointer to the setter a.prop //same as h h = 3; //illegal h(3); //OK, equates to a.prop = 3; Reason: This needs to be possible, but using & for it is broken. The most important thing is to keep the syntax of common use-cases clean and unsurprising. ***any other workable syntax for this is ok, __traits is just an (ugly, verbose) example*** Losing all property-ness when working through a function pointer keeps things simple. 4) OPTIONAL: Free functions can be marked as properties, with the same rules applied to them as properties in aggregates, except they must take 1 or 2 arguments instead of 0 or 1. Reason: Free functions and ufcs => good for encapsulation and nice to look at. Is there any reason why not to allow us to declare free properties? These rules should provide the least possible surprise and breakage, as far as I can tell. I don't think personally I would have to alter a single line of my code. What inevitable corner-cases have I missed?
Aug 10 2013
Part 1 - Ordinary Functions (the rewrite rules) -------------------------- Not strictly the discussion topic, but it was a big issue and is related, so: Q: Do you think the "property" rewrite rules (ie optional opCall operators) are a bad idea. A: Yes I do Q: Why? A1: Look at all the confusion its caused! A2: Because I have shot myself in the foot too many times because of this to be convinced otherwise. Judging from the posts, I am not the only one hopping around on one foot. Q: Accepting that it's here to stay, what can you do about it? A: Pretend they don't exist and always write expressions the "correct" way. Basically If you're having problems with the "property" rewrite rules, then stop trying to use them. Adopt the habit of always writing your function calls verbosely (even with UFCS) and your problems should go away. Unless they are going to be gotten rid of entirely, the rewrite rules should not be changed. All of the suggestions I've seen (including Walter's original one) will only lead to more complexity, more special cases, more inconsistency, more confusion, and more problems. Part 2 - property -------------------------- A big problem with property is that people are thinking of them as functions, no small part due to the "property" rewrite rules discussed above. Even people who suggest that properties should not use opCall still talk about calling properties, as though they are functions. The trick is to stop thinking of properties in terms of functions, and to think of them as variables. To "call" a property should make as much sense as calling a variable. Some have mentioned this, and others have hinted at it, but I think that it has not been made fully clear. To illustrate, consider this: int v; v is a reference to a block of memory which is accessed by a machine code getter and setter. So int a; is really property { int a() { fetch from memory }; int a(int) { write to memory } } When you're declaring a true property, you're still declaring a variable, but you're simply providing the complier with altertives to the traditional fetch/write instructions. ------------------------------ Here is another (admittedly more complex) way to look at it. struct { int opAssign(int) { ... }; int opCast!(int) { ... } ; } Property Property prop; You will need to imagine the opCast as an implicit cast for it to work, but hopefully you will get what I mean. Here prop is a variable, so it would be parsed like one by the compiler. The expression "prop = 3" would assign 3 to the contents of prop, Which would result in the opAssign (the setter) being called. In the expression "y = prop++", we get the contents of prop (via opCast, the getter), apply the ++ operator to it, and assign the result to y. If prop were an actual integer, the above expressions would work exactly the same way. Using struct for this is a little ugly, so you could say instead: property { int prop(int) { ... }; int prop() { ... }; } A little neater, but would work the same way. Part 3 - functions returning delegates. --------------------------------------- When it comes to delegate properties (ie the getter returns a delegate), I'm sensing that people are having trouble getting their heads around it, always needing to treat it like a special case. Let's try to see it in a way that it is not special. Lets have delegate int() f1; and property delegate int() f2() { ... }; In the eyes of the greater world f1 and f2 should work the same way. In the expression y = f1(), we get the contents of f1 (the delegate), apply the "()" operator to it, and assign the result to y; In the expression y = f2(), we get the contents of f2 (via the getter, which gives us the delegate), apply the "()" operator to it, and assign the result to y; In both cases y is an int. Recall an eariler statement: In the expression "y = prop++", we get the contents of prop (via opCast, the getter), apply the ++ operator to it, and assign the result to y. Note the similarity. () is like other operators and is no longer special. How does this work for ordinary functions? int func() can be seen as auto func = function int() func is a variable and its contents is the function. The expression func() means "get the contents of func (the function) an apply () to it (gives int)". For delegate int() delg() which can be seen as auto delg = function (delegate int())() The expression delg() means "get the contents of delg (the function) and apply () to it (gives delegate)", and delg()() would apply () to whatever delg() gives and, ultimately, give us an int. ---------------------------------- How come people are getting confused about it? That damn optional opCall rewrite rule. Some people probably think that, for functions returning delegates, if f becomes f() then f() becomes f()() THIS DOES NOT HAPPEN! Nor should it. Remember that and you should be OK. Otherwise consider my suggestion in Part 1. Part 4 - Answering the original question. ---------------------------------------- Should property be shot? No, but it should be reworked Regards Jason
Aug 11 2013