digitalmars.D - Reddit: why aren't people using D?
- Walter Bright (1/1) Jul 22 2009 http://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_pro...
- Michiel Helvensteijn (44/44) Jul 22 2009 Here's the opinion of an 'outsider'. I've experimented a bit with D in t...
- Ary Borenszweig (14/67) Jul 22 2009 Don't agree. It's nice to have this distinction when you care about
- Walter Bright (95/147) Jul 22 2009 Ok.
- Jarrett Billingsley (5/8) Jul 22 2009 This is EXACTLY the point I always try to make to newcomers. It's so
- Trass3r (28/38) Jul 22 2009 Seconded.
- Bill Baxter (7/15) Jul 22 2009 go
- Walter Bright (6/9) Jul 22 2009 It's like a car from the 60's vs a car today. It's hard to see what's
- Andrei Alexandrescu (3/9) Jul 22 2009 Or like driving an American car vs. a Japanese or European car.
- Jarrett Billingsley (6/7) Jul 22 2009 Yeah, what *is* the deal with that? In terms of little convenience
- Andrei Alexandrescu (4/14) Jul 22 2009 Would you believe there is a guy in this newsgroup who'd manage to keep
- Bill Baxter (13/23) Jul 23 2009 o
- Walter Bright (5/7) Jul 23 2009 I was just over in one of the restoration forums, where they're talking
- Adam D. Ruppe (9/17) Jul 22 2009 Agreed. This is the big benefit, but the hard part is that it takes some
- Bill Baxter (5/19) Jul 22 2009 Even that does have a cumulative effect, though. If you keep hearing
- Walter Bright (8/11) Jul 22 2009 Right. Just keep making comments about D in public forums in appropriate...
- Michiel Helvensteijn (74/162) Jul 23 2009 But in C++ you can put a class object on the stack with value semantics,
- Andrei Alexandrescu (11/42) Jul 23 2009 I think C++ does not handle inheritance in value types all that well, in...
- Michiel Helvensteijn (8/15) Jul 23 2009 Walter said something similar. I'm curious, which collision are you
- Andrei Alexandrescu (7/24) Jul 23 2009 The issues are discussed in the book C++ Coding Standards and also in
- Michiel Helvensteijn (12/15) Jul 23 2009 I'm aware of slicing. I didn't really think of it as a problem. But now ...
- Rainer Deyke (6/11) Jul 23 2009 Yes, C++ has problems, but these problems can be fixed! The
- Andrei Alexandrescu (4/15) Jul 23 2009 Again: what are those problems?
- Rainer Deyke (16/25) Jul 23 2009 Proposal 1: instances of polymorphic classes are stored on the heap but
- Walter Bright (4/11) Jul 23 2009 I was initially thrown by this when I started some Java programming. But...
- Rainer Deyke (9/15) Jul 23 2009 I like it in Python, where all variables are references. Java is
- Walter Bright (4/18) Jul 23 2009 Is C++ really better in that regard? Given a non-trivial struct or class...
- Rainer Deyke (14/27) Jul 24 2009 Yes, it is. Mainly because C++ doesn't have reference types in same way
- Walter Bright (6/19) Jul 24 2009 A reference type isn't defined as one that only exists on the heap. Even...
- Leandro Lucarella (22/36) Jul 24 2009 !? It's true that in Python all are references, but there are inmutable
- Rainer Deyke (13/16) Jul 24 2009 Immutable reference types are still reference types, and follow the same
- Walter Bright (9/21) Jul 24 2009 From a user's point of view, an immutable reference is
- Leandro Lucarella (14/29) Jul 24 2009 That's true, conceptually, but when you use the variables, you use them ...
- Rainer Deyke (8/10) Jul 24 2009 I want a programming language that enables me to write good code, not
- Jarrett Billingsley (11/14) Jul 23 2009 You know, this is like the first thing C++ users complain about on the
- Steven Schveighoffer (19/31) Jul 23 2009 I did.
- Jarrett Billingsley (3/5) Jul 23 2009 Um, did you? Because you can have custom allocators for classes too..
- Leandro Lucarella (10/18) Jul 23 2009 And that reason only seems to be a complain with the GC performance, not
- Steven Schveighoffer (12/19) Jul 23 2009 First, there were other reasons, such as I don't need polymorphism or
- Jarrett Billingsley (10/13) Jul 23 2009 e to
- Rainer Deyke (8/11) Jul 23 2009 In my first (and to date only) D project, *all* my user-defined types
- Jarrett Billingsley (3/11) Jul 23 2009 And you don't think that has *anything* to do with trying to program C++...
- Rainer Deyke (5/12) Jul 23 2009 No, it was clearly a case of trying to program D2 in D1. In D2, all of
- Walter Bright (47/134) Jul 23 2009 Not at all. How would you declare a type that is "pointer to immutable
- Steven Schveighoffer (28/40) Jul 23 2009 It leads to making things look like properties when they are not.
- Ary Borenszweig (8/22) Jul 23 2009 Semantic difference: a property doesn't have *visible* side effects. If
- Walter Bright (6/23) Jul 23 2009 Ok, but not having visible side effects is just a convention, one which
- Daniel Keep (12/37) Jul 23 2009 That's true, but you haven't addressed the other side of it: property
- Walter Bright (6/11) Jul 23 2009 Right. Consider the case where there's a pure function with no
- Daniel Keep (24/38) Jul 24 2009 Actually, I've now come up with a counter-example for the idea of using
- Ary Borenszweig (5/45) Jul 24 2009 Exactly! That's why I said "kind of pure" (well, maybe I didn't say that...
- Nick Sabalausky (8/11) Jul 24 2009 Speaking of that, has my top-level post about that (Subject: "DIP4:
- Nick Sabalausky (3/16) Jul 24 2009 My stuff seems to still be showing up fine in this thread...
- Lars T. Kyllingstad (3/18) Jul 24 2009 I can see three posts by you in the DIP4 thread.
- Nick Sabalausky (8/23) Jul 24 2009 Strange, I still can't see the thread at all, and I've never had trouble...
- Lars T. Kyllingstad (7/31) Jul 24 2009 Actually, on closer inspection, it turns out there are three separate
- Walter Bright (3/5) Jul 24 2009 That's right, lazy evaluation can't be pure. So, the question is is this...
- Steven Schveighoffer (11/16) Jul 24 2009 Don't get lost in the pure discussion. There are many reasons to have a...
- Walter Bright (3/7) Jul 24 2009 That's my problem with properties as a distinct syntax - they don't have...
- Steven Schveighoffer (22/29) Jul 24 2009 If you delineate what can be called how, then you elminate syntax
- Ary Borenszweig (13/48) Jul 24 2009 Maybe what scares Walter is a whole new syntax for properties. If at
- Steven Schveighoffer (13/17) Jul 24 2009 His point is that there are no benefits to the semantic meaning of the
- Bill Baxter (19/35) Jul 24 2009 st
- Walter Bright (5/6) Jul 24 2009 It doesn't scare me. It's trivial to add more syntax.
- Michel Fortin (26/29) Jul 24 2009 You know. I agree with you on that point. Earlier, in a thread no one
- Steven Schveighoffer (7/13) Jul 27 2009 OK, so you don't like the idea of adding dedicated properties.
- Bill Baxter (9/24) Jul 27 2009 I think his suggestion was the Java-style approach -- special naming
- Steven Schveighoffer (11/41) Jul 27 2009 Really? I got the impression that he does not think properties warrant ...
- Andrei Alexandrescu (5/35) Jul 27 2009 For one thing I like that I now get to define empty() for a range and
- Steven Schveighoffer (31/63) Jul 27 2009 The "getter" notation that currently exists only has a few minor
- bearophile (7/13) Jul 27 2009 An alternative:
- Steven Schveighoffer (9/20) Jul 27 2009 No, that is a different proposal. All I was saying is if property is an...
- Andrei Alexandrescu (38/72) Jul 27 2009 Thanks for a very lucid analysis! So let me give an example:
- escalan (8/96) Jul 27 2009 Hi, I'm new here. A simple idea I've had is to simply use aliases for de...
- Jarrett Billingsley (3/10) Jul 27 2009 Except if you want to do anything more complex in your setter/getter
- Jarrett Billingsley (5/20) Jul 27 2009 Also, if your suggestion really did just replace any accesses to the
- Steven Schveighoffer (94/133) Jul 28 2009 You're welcome :)
- Andrei Alexandrescu (9/67) Jul 28 2009 I think inferring meaning from the presence or absence of "()" is rather...
- Steven Schveighoffer (22/33) Jul 28 2009 Really? Then why name your functions things like empty, why not ex245, ...
- Andrei Alexandrescu (21/65) Jul 28 2009 Well it doesn't.
- Steven Schveighoffer (53/99) Jul 28 2009 No, you're saying inferring meaning from parentheses is not a good idea....
- Andrei Alexandrescu (32/156) Jul 28 2009 I acknowledge that in C, C++, and Java, you must add () to call an
- Steven Schveighoffer (77/141) Jul 28 2009 Yes, I agree. But there is also a subtle problem we can solve at the sa...
- Bill Baxter (21/46) Jul 28 2009 re to
- Steven Schveighoffer (19/35) Jul 28 2009 I think in the sense that 'seconds' is not a verb, and therefore, it's n...
- Andrei Alexandrescu (6/33) Jul 28 2009 I don't think it's a good argument. Operators are functions with a
- Steven Schveighoffer (42/76) Jul 28 2009 I was using this as an example of how your arguments against property
- Andrei Alexandrescu (5/10) Jul 28 2009 You can. In either C# or D language it could execute arbitrary code that...
- Steven Schveighoffer (6/13) Jul 28 2009 still not getting it, are you...
- Andrei Alexandrescu (8/24) Jul 28 2009 I do read them and understand them. I mean, it's not rocket surgery. At
- aarti_pl (10/36) Jul 28 2009 You should just accept what others want *although* you don't agree...
- Ary Borenszweig (4/43) Jul 28 2009 I'd like to see a poll about this. I think just a few want the ability
- Andrei Alexandrescu (9/46) Jul 28 2009 I do get his arguments. Not being convinced does not mean I don't
- bearophile (8/11) Jul 28 2009 Designing a language with polls is an obvious idea, but I have not sugge...
- Andrei Alexandrescu (11/23) Jul 28 2009 Great thoughts. One thing that maybe is not clear is that I afford to
- bearophile (7/9) Jul 28 2009 I want to add two small things:
- Ary Borenszweig (3/13) Jul 28 2009 Do you know such a poll system that's free? I just created a poll, but
- bearophile (4/5) Jul 28 2009 Just to be sure of what I mean: it mans you can express a vote in the cl...
- Bill Baxter (20/37) Jul 28 2009 I think the expectation is more that you would address or respond to
- Andrei Alexandrescu (18/57) Jul 28 2009 Well we both repeated our arguments several times :o). And don't forget:...
- Bill Baxter (14/53) Jul 28 2009 I
- Andrei Alexandrescu (3/28) Jul 28 2009 Oh yeah? How about "lazy"?
- Bill Baxter (9/40) Jul 28 2009 : I
- Steven Schveighoffer (11/31) Jul 28 2009 No, b has no meaning. It's not an English word.
- Benji Smith (15/41) Jul 30 2009 I totally agree with Steven's arguments (and have enjoyed reading the
- Bill Baxter (35/76) Jul 28 2009 mare
- Sergey Gromov (16/23) Jul 28 2009 I think the reason is purely syntactical. Specifically to distinguish
- Ary Borenszweig (7/23) Jul 28 2009 Back to semantics by convention?
- Andrei Alexandrescu (4/31) Jul 28 2009 I was replying to the expectation that a.foo() does an action and a.foo
- Rainer Deyke (18/18) Jul 28 2009 I C++, I write a lot of functions with names in the form of get_foo,
- Ary Borenszweig (4/14) Jul 28 2009 Just because it could do anything doesn't mean it *has* to do anything.
- Sergey Gromov (4/16) Jul 28 2009 I think it is mentioned more often because you tend to agree with it.
-
=?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?=
(12/20)
Jul 28 2009
- Andrei Alexandrescu (6/20) Jul 28 2009 But then they'd expect a number of improvements wouldn't they. To me,
- Adam D. Ruppe (5/8) Jul 28 2009 For what it's worth, I agree with this.
- Michel Fortin (17/21) Jul 28 2009 This may lead to strange issues if both the setter and the getter don't
- Andrei Alexandrescu (6/27) Jul 28 2009 Well I chose the rule that makes bar look and feel as much as an
- Michel Fortin (24/52) Jul 28 2009 Also, what if a derived class implements a getter while the base class
- Andrei Alexandrescu (12/62) Jul 28 2009 It all follows normal language rules. That's what I like about rewrites
- Rainer Deyke (6/13) Jul 24 2009 My proposal requires no new keywords and no new syntax:
- Andrei Alexandrescu (4/17) Jul 24 2009 This is pretty clean, and in keep with the opXxx approach. Actually how
- Michel Fortin (14/16) Jul 24 2009 The problem with this is that it's ugly. What about this
- Lutger (3/23) Jul 24 2009 There is a thread discussing the proposal which is also linked to by the...
- Daniel Keep (50/69) Jul 25 2009 Actually, if this became the "official" way of doing properties, that
- Steven Schveighoffer (10/24) Jul 26 2009 I would be OK with defining properties any of these ways. Although the ...
- Walter Bright (5/25) Jul 24 2009 But when I suggest a restriction on properties, I get complaints that
- Nick Sabalausky (22/47) Jul 25 2009 I'm not sure what restriction you're talking about, but here's the
- Nick Sabalausky (12/51) Jul 25 2009 With that ball/moveTo/position stuff, I should also clarify that for mos...
- Steven Schveighoffer (6/33) Jul 25 2009 The only thing that properties can't do that functions can is be called ...
- Michiel Helvensteijn (32/35) Jul 24 2009 You know, I don't believe I've seen you reply specifically to any of the
- Steven Schveighoffer (16/19) Jul 24 2009 This is typical Walter :) He'll argue the easy ones all day long, and
- Walter Bright (4/10) Jul 24 2009 I spent literally all day in this thread yesterday. Each reply I make
- Walter Bright (4/6) Jul 24 2009 Let's start with:
- Bill Baxter (18/26) Jul 24 2009 """
- Lutger (19/27) Jul 24 2009 A property contains information describing some object, which may or may...
- Michiel Helvensteijn (7/13) Jul 24 2009 I agree with Bill's reply to this one.
- Daniel Keep (58/66) Jul 24 2009 A piece of state referred to by some name; state which is usually part
- Steven Schveighoffer (12/16) Jul 26 2009 I agree with this. A property should only be callable by the debugger i...
- Michiel Helvensteijn (66/142) Jul 23 2009 Then perhaps you can get rid of enum and have only immutable. Well, I'm ...
- Don (6/21) Jul 24 2009 That's not what the documentation means. * is only 'default
- Lutger (6/12) Jul 23 2009 The major point about properties is imo not a semantic issue at all, it'...
- Leandro Lucarella (24/31) Jul 23 2009 When I see this, I think about this:
-
Walter Bright
(3/7)
Jul 23 2009
That is a good point. I won't say I'm convinced for the tuple case
, - Leandro Lucarella (9/17) Jul 24 2009 I can't believe it, I actually made Walter think something twice! =P
- Tom S (38/40) Jul 23 2009 Why is dedicated syntax for comma expressions better than commaExpr(...)...
- Adam D. Ruppe (12/13) Jul 23 2009 What do you propose we do about the commas in loops? Breaking them
- Michiel Helvensteijn (8/9) Jul 23 2009 There are ways -- elegant ways, I believe -- to make it work.
- Adam D. Ruppe (15/16) Jul 23 2009 Looking at it quickly, the big difference seems to be you leave the tupl...
- Michiel Helvensteijn (9/11) Jul 23 2009 Hm. Then I believe you haven't read the whole thing. (That's ok, it does...
- Adam D. Ruppe (13/15) Jul 23 2009 Yeah, I just briefly skimmed it. I'll have to go back to it for a full r...
- Tom S (13/35) Jul 23 2009 It's not much worse, but it's not everything that's to tuples. Here's
- Adam D. Ruppe (26/34) Jul 23 2009 Why would you ever want to do that when you have:
- Jesse Phillips (2/20) Jul 23 2009 Thanks for the tutorial, expect to see it on Wiki4D within a year :D
- Adam D. Ruppe (20/21) Jul 23 2009 This actually doesn't /quite/ work, since the tuple returned by tuple() ...
- Jesse Phillips (3/32) Jul 23 2009 Thanks, truth be told I don't know why that first one works. But the
- Leandro Lucarella (21/50) Jul 24 2009 And you still think that's not remarkably worse than something like:
- Jesse Phillips (5/32) Jul 24 2009 I would say it isn't remarkably worse. The other one though, that was
- Leandro Lucarella (14/19) Jul 25 2009 It has, providing tuples without that generally doesn't need language
- Rainer Deyke (9/13) Jul 25 2009 From the Boost.Tuple documentation:
- Adam D. Ruppe (5/13) Jul 25 2009 I think I like that.
- Leandro Lucarella (10/24) Jul 25 2009 But you have to split declaration from initialization. That's not nice.
- Adam D. Ruppe (7/9) Jul 25 2009 Interestingly, I've been looking at tuples almost entirely as "anonymous
- Tom S (9/10) Jul 23 2009 Remember delegate literals? They were just a few more tokens, but it
- Bill Baxter (6/15) Jul 23 2009 Uh, yes. Yes it is.
- Adam D. Ruppe (9/15) Jul 23 2009 And I'm amazed at the illegibility some people are apparently willing to
- bearophile (5/7) Jul 27 2009 Disallowing bad usages of commas is a starting point. for() can become a...
- Jarrett Billingsley (4/6) Jul 23 2009 It's trivial to allow a comma-separated list of expressions in the for
- Walter Bright (5/6) Jul 23 2009 What bothers me about overloading && and || is they are control flow
- Daniel Keep (2/11) Jul 24 2009 Ask downs about that one :3
- Jarrett Billingsley (7/12) Jul 22 2009 Ha. Had D differed *too* much from C++, then we'd run the risk of
- Walter Bright (6/11) Jul 22 2009 It's a good point. Radically different languages tend to fail simply
- language_fan (15/23) Jul 29 2009 Do you think it is the syntax or the semantics that is the cause? D is
- Nick Sabalausky (32/34) Jul 22 2009 Even as a former die-hard C/C++ user, I've never really understood this
- Rainer Deyke (8/11) Jul 22 2009 And if D had just one of these features, plus all of the useful features
- Walter Bright (12/47) Jul 22 2009 It does take time and effort to learn a new tool, and that effort needs
- Rainer Deyke (14/19) Jul 22 2009 I want to throw these words back at you, because my first impression of
- Walter Bright (13/24) Jul 23 2009 One measure of messy language semantics is the messiness of the compiler...
- Rainer Deyke (10/17) Jul 23 2009 1. C++'s object model, complete with polymorphic value types,
- Andrei Alexandrescu (17/31) Jul 23 2009 Struct have that except for default constructor. In D, currently default...
- Rainer Deyke (50/69) Jul 23 2009 In a way, that's a loaded question, since C++ classes don't stay
- Walter Bright (11/54) Jul 23 2009 It should be a different mechanism to show that it is a very different
- Bill Baxter (13/18) Jul 23 2009 I think the case he's talking about is just a sort of optimization to
- Rainer Deyke (38/76) Jul 23 2009 Composition instead of inheritance? Doesn't work if I need virtual
- Bill Baxter (12/28) Jul 23 2009 I don't get your meaning in that last sentence. What's the problem of
- Andrei Alexandrescu (4/13) Jul 24 2009 This is going in circles. You started from "implementation inheritance
- Rainer Deyke (9/15) Jul 24 2009 Yes, but implementation inheritance may involve customization points.
- Andrei Alexandrescu (22/77) Jul 24 2009 I'll try to briefly reply to this (I've been offline since yesterday's
- Rainer Deyke (17/21) Jul 24 2009 My take on composition vs inheritance is very simple: always use
- Andrei Alexandrescu (3/16) Jul 24 2009 Whether we like it or not, programming has a large social component.
- Walter Bright (5/11) Jul 24 2009 I've been writing software for 35 years. I'm still learning new ways of
- Andrei Alexandrescu (3/10) Jul 24 2009 But goto will never die :o).
- Sergey Gromov (6/17) Jul 26 2009 This means that structs cannot hold on external resources, ever:
- Andrei Alexandrescu (3/21) Jul 26 2009 You may be making a confusion between assignment and copy construction.
- Sergey Gromov (7/28) Jul 27 2009 Sure I'm confusing them, silly me.
- Rainer Deyke (7/12) Jul 27 2009 The "linked list" implementation of smart pointers also requires a copy
- Walter Bright (3/8) Jul 23 2009 I'm with Andrei in saying that polymorphic value types are a very bad
- Nick Sabalausky (11/24) Jul 23 2009 D is certainly a bit messy compared to many languages, but I have a very...
- sclytrack (46/54) Jul 23 2009 My experience with D people sticking with it is ...
- Ary Borenszweig (4/51) Jul 23 2009 Unfortunately the designers of D doesn't care at all about IDE support
- Andrei Alexandrescu (9/12) Jul 23 2009 The problem is not not caring. For one, I'd love a D IDE as much as the
- Ary Borenszweig (10/22) Jul 23 2009 I'm not talking about writing an IDE. I'm talking about when thinking of...
- Eldar Insafutdinov (2/22) Jul 23 2009 While working on QtD I have also come up with the conclusion that D need...
- Lutger (5/18) Jul 23 2009 There have been a lot of discussions on this topic in the past but I can...
- Michiel Helvensteijn (7/10) Jul 23 2009 Property DIPs have been offered in the newsgroup in the past, only befor...
- Bill Baxter (23/31) Jul 23 2009 """
- Lutger (3/6) Jul 23 2009 At least it's not 5 like vb.net, but that beast already has 150 keywords...
- Bill Baxter (9/15) Jul 23 2009 I do think it would be justifiable to add one more keyword for real
- Steven Schveighoffer (7/17) Jul 23 2009 I think you might be wrong. operator functions like opAdd are not
- Bill Baxter (10/27) Jul 23 2009 :
- Michiel Helvensteijn (18/33) Jul 23 2009 Nope. Never used C#, never seen it. I just think about language design a
- Michiel Helvensteijn (4/5) Jul 23 2009 Small correction: x.set(v)
- Eldar Insafutdinov (8/24) Jul 23 2009 from your post:
- Michiel Helvensteijn (12/24) Jul 23 2009 If your property really just hides a private member variable, it was
- Jarrett Billingsley (13/35) Jul 23 2009 ed
- Michiel Helvensteijn (18/29) Jul 24 2009 It may not be necessary in simple situations where the compiler can figu...
- Andrei Alexandrescu (3/43) Jul 24 2009 I think this would be inefficient in many cases.
- Jarrett Billingsley (9/15) Jul 24 2009 Um, what do you have to write now? "obj.prop = obj.prop op value".
- Bill Baxter (16/64) Jul 24 2009 st
- Andrei Alexandrescu (3/62) Jul 24 2009 Ok, I got convinced.
- Jarrett Billingsley (15/85) Jul 24 2009 h
- Nick Sabalausky (4/8) Jul 23 2009 http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4
- Nick Sabalausky (3/14) Jul 23 2009 Erm... I mean right here on digitalmars.D...
- goooooo (4/4) Jul 24 2009 It is said that "Character decided fate" .
- Walter Bright (5/10) Jul 24 2009 I am not and never was associated with Watcom C in any way, other than
- Ary Borenszweig (3/15) Jul 24 2009 http://www.walterbright.com/garage/index.html
- Jarrett Billingsley (3/20) Jul 24 2009 What! Descent! You don't SELL Descent. You treasure it for years
- Walter Bright (7/9) Jul 24 2009 Bah, I have a basement full of such treasures.
- Andrei Alexandrescu (3/24) Jul 24 2009 Yes please.
- Walter Bright (2/5) Jul 23 2009 Must be those classicempire affiliate links!!!
- Andrei Alexandrescu (6/8) Jul 23 2009 I think D should also visibly obviate some use of Python or Perl for
- Sergey Gromov (5/7) Jul 27 2009 I'm planning to write a DIP on better tuple support. Here is a brief
- Andrei Alexandrescu (5/6) Jul 22 2009 I noticed some people complain about installation difficulties, is there...
- Adam D. Ruppe (27/32) Jul 22 2009 I think the installation difficulties are the result of poor instruction...
- Walter Bright (2/7) Jul 22 2009 Please post patches to bugzilla!
- Nick Sabalausky (9/12) Jul 23 2009 Really? That surprises me. I consider myself relatively green when it co...
- Michiel Helvensteijn (5/6) Jul 23 2009 Linux Gentoo does have DMD in portage, by the way. apt-get easy. Or, to ...
- naryl (4/10) Jul 23 2009 Available versions: (~)1.016!m!s (~)2.008-r1!m!s
- Michel Fortin (14/20) Jul 22 2009 I
- Jesse Phillips (8/16) Jul 22 2009 I'm intending a rework of:
- Andrei Alexandrescu (18/39) Jul 22 2009 Thanks, we need more of that stuff. I think this is a common experience
- Jesse Phillips (13/56) Jul 22 2009 Oh, I know, I posted this response:
- Jacob Carlborg (4/10) Jul 23 2009 Yes: http://www.dsource.org/projects/dmd-installer
- Michel Fortin (21/23) Jul 23 2009 Speaking of that OS X DMD installer, are you sure installing it at
- Walter Bright (2/10) Jul 23 2009 I've been switching the directories to {dmd, dmd2} so they can coexist.
- Jarrett Billingsley (3/14) Jul 23 2009 Will you rename the DMD2 compiler to 'dmd2' as well?
- Lutger (2/18) Jul 23 2009 That would be very convenient, please consider this.
- Andrei Alexandrescu (4/22) Jul 23 2009 I think moving forward D2 will be the norm, so I suggest going with dmd1...
- Jarrett Billingsley (5/32) Jul 23 2009 Yeah, let me know when that happens. Until then, I'd like to continue
- Walter Bright (23/26) Jul 23 2009 I don't know what build tools you're using, but consider make:
- Jarrett Billingsley (7/13) Jul 23 2009 Walter, I'm pretty shocked by this response. How long have Bud and
- Walter Bright (3/4) Jul 23 2009 Ok, now about make's ability to switch compilers without having to edit
- Jarrett Billingsley (3/8) Jul 23 2009 So editing every make file you have is better? :P
- Jarrett Billingsley (3/13) Jul 23 2009 Ah, nevermind.
- grauzone (7/13) Jul 23 2009 So that's the killer feature of make? I don't know about you, but I
- Don (7/13) Jul 24 2009 I don't do it that way. I can't imagine when you would mix D1 and D2 in
- Michel Fortin (9/24) Jul 24 2009 My opinion is that the best way forward is to have dmd1, dmd2, and a
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (29/40) Aug 01 2009 And for GNU make, it uses the variables $(DC) and $(DMD)
- Lutger (3/28) Jul 23 2009 Also fine, as long as they are different to ease more complex setups, pl...
- Bill Baxter (12/40) Jul 23 2009 Shouldn't the strategy taken be something more akin to what
- Lutger (5/54) Jul 23 2009 Yes, I admit this is the preferred and in the end only sane way of doing...
- Walter Bright (3/4) Jul 23 2009 No. If they're in different directory trees, there's no reason to. After...
- Bill Baxter (7/12) Jul 23 2009 That seems to be the way they do things in Windows, but usually they
- Michel Fortin (9/20) Jul 23 2009 I know. But the OS X installer I see on dsource doesn't seem to reflect
- Jacob Carlborg (5/25) Jul 31 2009 Sorry I haven't replied sooner I've been on vacation.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (8/12) Aug 01 2009 You can use /opt/dmd and /opt/dmd2, if you don't
- Michel Fortin (22/38) Aug 01 2009 In hier(7), it says that "/usr/local" is for "executables, libraries,
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (12/17) Aug 01 2009 I normally* use the regular /usr/local/bin and
- Sergey Gromov (9/50) Aug 01 2009 Here's a nice document about directory layout in UNIX-like OSes:
- Michel Fortin (17/27) Aug 01 2009 Well, given that this is Mac OS X we could also put this in
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (14/26) Aug 02 2009 That's how the zip files work, yes ? Possibly PATH instead of symlinks.
- Jacob Carlborg (6/29) Aug 03 2009 I think I like /usr/local best. /Library is used for resources:
- Michel Fortin (10/17) Aug 03 2009 "The
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (8/19) Aug 03 2009 The objection (if any) was mostly about "/usr/local/dmd/osx/bin"
- Jacob Carlborg (5/24) Aug 07 2009 I was thinking about using /usr/local/{dmd,dmd2} and then create
- Michel Fortin (12/25) Aug 07 2009 The solution is to create a "symlink program" and drop it in
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (8/25) Aug 07 2009 I did that for my linux package, but used shell instead.
- Jacob Carlborg (12/37) Aug 12 2009 If I understand you correctly you have a symlink "/usr/bin/dmd2"
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (11/43) Aug 12 2009 Right, /usr/libexec/dmd2/dmd is the actual program.
- Michel Fortin (6/11) Aug 12 2009 That's something I'd really like to see.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (14/21) Aug 13 2009 It's done the same with GCC, too:
- Michel Fortin (9/13) Aug 07 2009 Also, could you make symlinks for "dmd" (prefered version), "dmd1" and
- Knud Soerensen (88/90) Jul 23 2009 Let me start with an example.
- Walter Bright (25/75) Jul 23 2009 I'd love to have some functions in Phobos that do this. Can you write a
- Lutger (27/48) Jul 23 2009 It's interesting why unittest (and assert) are such big success. My idea...
- Walter Bright (8/12) Jul 24 2009 I tend to agree. I've found over and over, that if you drive things down...
- Steven Schveighoffer (8/21) Jul 24 2009 Downloading, unzipping (where?), setting up your path, marking the binar...
- Knud Soerensen (40/101) Jul 23 2009 Yes, but the chose is not about unit test or no unit test.
- Jesse Phillips (4/23) Jul 23 2009 But those languages don't have Unit testing. There are libraries that le...
- Nick Sabalausky (20/28) Jul 23 2009 .....
- bearophile (58/74) Jul 27 2009 Lazy parameters allow me to implement a poor's man list comprehensions.
- Michiel Helvensteijn (11/19) Jul 27 2009 This was about overloading &&, || and !, right?
- Lutger (10/58) Jul 27 2009 Yes, but practically every other language implements testing in librarie...
- bearophile (6/11) Jul 27 2009 Nope. Lazy/eager sequence comprehensions can be useful in many situation...
- Lutger (8/21) Jul 27 2009 Sure, I was referring to your suggestion of adding features to see how t...
- bearophile (13/16) Jul 27 2009 Yes, there's a small contradiction there, because usually there's no a s...
- Lutger (9/9) Jul 27 2009 python:
- bearophile (6/18) Jul 27 2009 It's not terrible, but it's far from being nice. Strings are sharp and r...
- Andrei Alexandrescu (3/17) Jul 27 2009 array.
- Andrei Alexandrescu (3/16) Jul 27 2009 (It's called iota.)
- Lutger (4/22) Jul 27 2009 Oh yes, I remember being freaked out reading about the APL after that on...
- bearophile (5/10) Jul 27 2009 [2, 3, 5, 7, 11, 13, 17, 19]
- Kagamin (3/16) Jul 27 2009 Your view of the problem is too technical.
- Andrei Alexandrescu (14/44) Jul 27 2009 I so don't get this. Yes, functions are used to denote arbitrary
- Ary Borenszweig (5/57) Jul 27 2009 I think the only way you and Walter can understand what a property is
- Andrei Alexandrescu (4/8) Jul 27 2009 I totally agree that "that's nice". But it's just notational
- Ary Borenszweig (4/14) Jul 27 2009 The ambiguity with a function returning a delegate? The debugger
- Andrei Alexandrescu (5/21) Jul 27 2009 Convince me of what? Of the fact that the current design has problems,
- Ary Borenszweig (2/25) Jul 27 2009 I agree. It's very hard to find the correct way to implement it... :(
- Andrei Alexandrescu (20/47) Jul 27 2009 Might be because (a) we aren't getting our priorities right, (b) we
- Ary Borenszweig (6/59) Jul 27 2009 Again, I agree. I think just a minimal change is required to accomplish
- Lutger (5/6) Jul 27 2009 That sums up the discussion pretty nicely. Except for one thing: what do...
- Andrei Alexandrescu (4/12) Jul 27 2009 They'd employ whatever means the language has for enabling the
- Nick Sabalausky (24/28) Jul 27 2009 I can't be nice about this: Any programmer who has *any* aggrivation
- Ary Borenszweig (2/8) Jul 27 2009 Throw while too, we have goto!
- Andrei Alexandrescu (7/39) Jul 27 2009 Sure. My point is that with using standard method definition syntax
- Andrei Alexandrescu (8/34) Jul 27 2009 PLUS:
- Nick Sabalausky (12/20) Jul 27 2009 So people are going to automagically just *know* to stick "opGet_" in fr...
- Andrei Alexandrescu (12/39) Jul 27 2009 It's ONE rule to remember, and it blends perfectly with the rest of the
- Bill Baxter (17/57) Jul 27 2009 Some other things to consider. Here's what Qt's property syntax looks l...
- Nick Sabalausky (4/8) Jul 27 2009 Well let's just throw away all our high-level syntax then and go back to...
- John C (4/31) Jul 27 2009 Which is why Steven Schveighoffer's is suggestion is the most pragmatic
- Bill Baxter (13/46) Jul 27 2009 get
- grauzone (15/48) Jul 27 2009 Also note that the syntactic sugar could be implemented as library,
- grauzone (2/7) Jul 27 2009 Oops, "annotations" is the term in use, not "attributes".
- Nick Sabalausky (3/10) Jul 27 2009 Either way. Java calls them annotations, C# calls them attributes.
- Steven Schveighoffer (4/7) Jul 27 2009 I'll note that I wasn't the first to suggest it... But I do think it's ...
- Rainer Deyke (15/28) Jul 27 2009 I don't know exactly how this is supposed to work. The basic idea is
- Andrei Alexandrescu (3/33) Jul 27 2009 +1
- Benji Smith (13/48) Jul 27 2009 Also agree. The C# syntax is a little too complex for my taste, and it
- Rainer Deyke (12/17) Jul 27 2009 I like being able to distinguish between the property itself and its
- Steven Schveighoffer (7/20) Jul 28 2009 This is a general problem with all overloaded functions. The answer is ...
- Michiel Helvensteijn (23/31) Jul 28 2009 May I remind the group of a possible solution I've offered before?
- KennyTM~ (18/39) Jul 28 2009 class X {
- sclytrack (67/74) Jul 27 2009 no
- KennyTM~ (2/95) Jul 28 2009
- Steven Schveighoffer (43/47) Jul 27 2009 Let me bring you back to the issue at hand:
- Andrei Alexandrescu (7/73) Jul 27 2009 That wart must be eliminated. But the shortcomings of the current design...
- Steven Schveighoffer (16/32) Jul 27 2009 I personally am OK with any solution that allows me to specify that a
- John C (6/47) Jul 27 2009 Agreed. And enabling the function pair to be enclosed in a block would r...
- Kagamin (3/21) Jul 28 2009 May be namespace states your complaints. It doesn't add a whole new synt...
http://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_programming_language_looks/
Jul 22 2009
Here's the opinion of an 'outsider'. I've experimented a bit with D in the past (years ago), but have lately just followed the newsgroup out of general interest. I respect the expertise and hard work of the D team, but I won't use D. And here's an incomplete list of my reasons. I imagine there are other programmers who share my views. Most of these issues, if not all, are well known here. But I'll mention them anyway. Please forgive (and correct) any factual mistakes. I'm sure there will be some. If you reply to any point in the list, I'll be glad to elaborate. D offers too many ways to do the same thing: * const, enum, immutable, invariant * structs, classes * functions, delegates, lazy parameter evaluation * garbage collection, manual D memory management, manual C memory management Even with so many ways to ensure const correctness, it is still possible to cast constness away, either making it impossible for the compiler to make any assumptions regarding constness, or making it very dangerous to do the cast. D offers some cool features, but leaves them very underpowered: * Contract programming (no contract inheritance, no compile-time static analysis, no loop invariants / ranking functions) * Class/Struct properties (no control over their use by class designer, no way to use +=, -=, no global properties, no parameterized properties) * Operator overloading (no fine control over comparison operators, fixed commutativity, confusing rule priority to determine translation, no overloading of !, &&, ||, <>=) * Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples) * Unit testing (not at compile time, not possible to categorize) There are two competing standard libraries for D. This has been discussed to death and I won't go further into it. But it's a bad thing. I maintain that D suffers greatly from its lack of a formal specification. It is silly for a language as old and relatively popular as D to use a compiler written by a small group of people (1 person?) as the official reference to the language. Not only does the D specification feel really unstable, it has a very low bus-factor. In other words: if, hypothetically, Walter were hit by a bus, would the D language survive? D just doesn't offer enough improvements over C++ to make it worthwhile switching over. Its design is not very adventurous, keeping simply too close to that of the C family, making it look like Yet Another C Language. I believe simply filling in the gaps of C++ wasn't enough to take over the world. There should have been a greater change. -- Michiel Helvensteijn
Jul 22 2009
Michiel Helvensteijn escribi:Here's the opinion of an 'outsider'. I've experimented a bit with D in the past (years ago), but have lately just followed the newsgroup out of general interest. I respect the expertise and hard work of the D team, but I won't use D. And here's an incomplete list of my reasons. I imagine there are other programmers who share my views. Most of these issues, if not all, are well known here. But I'll mention them anyway. Please forgive (and correct) any factual mistakes. I'm sure there will be some. If you reply to any point in the list, I'll be glad to elaborate. D offers too many ways to do the same thing: * const, enum, immutable, invariantAgree.* structs, classesDon't agree. It's nice to have this distinction when you care about performance. I just removed a class from a Java project and replaced it with a pair of parameters because too many instances of it were created. and it's ok.* functions, delegates, lazy parameter evaluation * garbage collection, manual D memory management, manual C memory managementIt's ok if you want to have finer control over the memory. Not everything is high-level.Even with so many ways to ensure const correctness, it is still possible to cast constness away, either making it impossible for the compiler to make any assumptions regarding constness, or making it very dangerous to do the cast. D offers some cool features, but leaves them very underpowered: 1. Contract programming (no contract inheritance, no compile-time static analysis, no loop invariants / ranking functions) 2. Class/Struct properties (no control over their use by class designer, no way to use +=, -=, no global properties, no parameterized properties) 3. Operator overloading (no fine control over comparison operators, fixed commutativity, confusing rule priority to determine translation, no overloading of !, &&, ||, <>=) 4. Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples) 5. Unit testing (not at compile time, not possible to categorize) 6. There are two competing standard libraries for D. This has been discussed to death and I won't go further into it. But it's a bad thing.It's amazing how many times 2, 5 and 6 were mentioned in this newsgroup. However nothing is done in this respect (maybe for 6 yes, but I think phobos should just dissapear).I maintain that D suffers greatly from its lack of a formal specification.For me, it's not the lack of a formal specification, but it's hard to find how something works. Navigating the site is a PITA.It is silly for a language as old and relatively popular as D to use a compiler written by a small group of people (1 person?) as the official reference to the language. Not only does the D specification feel really unstable, it has a very low bus-factor. In other words: if, hypothetically, Walter were hit by a bus, would the D language survive? D just doesn't offer enough improvements over C++ to make it worthwhile switching over. Its design is not very adventurous, keeping simply too close to that of the C family, making it look like Yet Another C Language. I believe simply filling in the gaps of C++ wasn't enough to take over the world. There should have been a greater change.
Jul 22 2009
Michiel Helvensteijn wrote:Here's the opinion of an 'outsider'. I've experimented a bit with D in the past (years ago), but have lately just followed the newsgroup out of general interest. I respect the expertise and hard work of the D team, but I won't use D. And here's an incomplete list of my reasons. I imagine there are other programmers who share my views. Most of these issues, if not all, are well known here. But I'll mention them anyway.Thanks for taking the time to let us know your thoughts.Please forgive (and correct) any factual mistakes. I'm sure there will be some. If you reply to any point in the list, I'll be glad to elaborate.Ok.D offers too many ways to do the same thing: * const, enum, immutable, invariantinvariant is deprecated and completely replaced by immutable. So now we're down to three <g>. The uses are: immutable - data that cannot change or be changed (imagine it is stored in ROM) const - read only view of data, you cannot change it but others can enum - compile time constant, has no storage The only place these overlap is in the declaration of symbolic constants. C++ has all three, but in a way that is context dependent that very few people are aware of.* structs, classesstructs are value types, classes are reference types. That's a fundamental distinction, not two ways to do the same thing. A lot of confusing problems with C++ code stem from attempting to use a struct (or class!) both ways, or trying to give it characteristics of both.* functions, delegates, lazy parameter evaluationLazy parameter evaluation may turn out to be a bad idea, it doesn't seem to have found its "groove" anywhere. On the other hand, you can just ignore them like everyone else does, like everyone ignores exception specifications in C++. There's some undeniable extra complexity in having both function pointers and delegates. At some level, function pointers must be supported in order to support the C interface. Delegates are just too useful to give up (C++ has had awful problems trying to work around not having them - member function pointers anyone? Boost::bind? no thanks). It is technically possible to wrap delegates with a thunk so they are interchangeable with function pointers, but this thunk has to be created at runtime. It'll have a corresponding performance and memory consumption penalty. It's hard to know if it's an acceptable cost or not.* garbage collection,Many programming paradigms are not practical without gc.manual D memory management,It's possible to do this, but rather pointless. It's only there for people who insist they need it.manual C memory managementNecessary to support the C ABI. But D actually does not have C memory management - to do C memory management, you call the C functions malloc/free. Those are not reimplemented in D. D programs have complete access to C runtime libraries, and naturally this includes any C memory management functions.Even with so many ways to ensure const correctness, it is still possible to cast constness away, either making it impossible for the compiler to make any assumptions regarding constness, or making it very dangerous to do the cast.Being a systems programming language, it must be possible to defeat the static type checking system for special cases. Yes, you can cast away constness, but (unlike in C++), if you use that power to change the value, you are in undefined territory. The compiler is allowed to assume that const-ness is respected. In C++, it is legal and defined behavior to cast away const (unless it is a top level const) *and* change the value. This makes const completely useless as a hint to the code generator.D offers some cool features, but leaves them very underpowered: * Contract programming (no contract inheritance, no compile-time static analysis, no loop invariants / ranking functions)True, but compile-time static analysis is a "quality of implementation" issue. Furthermore, I know of no language other than Eiffel that has all this, and nobody uses Eiffel.* Class/Struct properties (no control over their use by class designer, no way to use +=, -=, no global properties, no parameterized properties)I don't understand what this means.* Operator overloading (no fine control over comparison operators, fixed commutativity,This is deliberate. Operator overloading should be restricted to implementing arithmetic like operations on objects, not completely different things like what iostreams, Spirit and Boost::regex do.confusing rule priority to determine translation,The alternative is "Koenig lookup", which I guarantee is far more confusing and has many weird problems.no overloading of !, &&, ||,That's deliberate. For !, I wish to maintain the property of negation of the boolean result, as much of the semantics of transformation depend on it. For && and ||, they are "short circuit" operators, and how that would sensibly interact with operator overloading I have no idea. I know of no language that allows overloading && and ||.<>=)I need to fix that.* Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples)The flattening thing is a problem. The rest can be done with better library support.* Unit testing (not at compile time,You can do testing at compile time with static asserts.not possible to categorize)I agree that D's built-in unit testing is basic. But the fact that it exists *at all* is a huge improvement for a programming language. I firmly believe that its mere existence has been a big factor in improving the general quality of D code. The fact that you want more from unit testing is great. Unit testing has raised the bar of expectations on a language, and in that it's a home run.There are two competing standard libraries for D. This has been discussed to death and I won't go further into it. But it's a bad thing.There is one standard library, Phobos, and an alternative, Tango.I maintain that D suffers greatly from its lack of a formal specification.Perhaps, but remember that most languages don't get formal specs until long after they become popular. Consider that C++ was defined by cfront for the first 10 or 12 years of its existence.It is silly for a language as old and relatively popular as D to use a compiler written by a small group of people (1 person?) as the official reference to the language.This is not true anymore. Several people are contributing substantial upgrades to it. I review everything before they get folded into the source tree, of course, but the quality of the submissions has been improving by leaps and bounds.Not only does the D specification feel really unstable,I admit I'm not good at writing language lawyer text. But the D1 spec isn't unstable. The feature set is set, it's pretty clear how it's supposed to work, there's a reference implementation to resolve disputes, and weaknesses in the spec get fixed. D2 is a work in progress, and so the spec for it is, too.it has a very low bus-factor. In other words: if, hypothetically, Walter were hit by a bus, would the D language survive?With the full release of the source code, and the growth of fully-capable third party D compilers, yes it will survive. I couldn't wreck the language if I tried <g>.D just doesn't offer enough improvements over C++ to make it worthwhile switching over. Its design is not very adventurous, keeping simply too close to that of the C family, making it look like Yet Another C Language. I believe simply filling in the gaps of C++ wasn't enough to take over the world. There should have been a greater change.In my experience, D code is about 30% less source code than the equivalent C++. That's a third off of development time, not including the debugging time saved. That's a very big deal. Many valuable improvements of D, such as memory safety guarantees, protections against function hijacking, etc., are surely "yeah, yeah, so what" unless one has managed large projects and been submarined by these problems. Much of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.
Jul 22 2009
On Wed, Jul 22, 2009 at 6:30 PM, Walter Bright<newshound1 digitalmars.com> wrote:Much of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.This is EXACTLY the point I always try to make to newcomers. It's so significant that I think it should be on the front page of the language spec, in bold, 72 point, red letters.
Jul 22 2009
Jarrett Billingsley schrieb:On Wed, Jul 22, 2009 at 6:30 PM, Walter Bright<newshound1 digitalmars.com> wrote:Seconded. Even though the road is paved with obstacles I can't imagine going back to C++ or any other language. By obstacles I mean among others: - D1<->D2 and Phobos<->Tango problem - esp. when creating a library that shall be compilable with any combination the end user wants you have to use a lot of versions and aliases to accommodate that, like it is done in DFL. - dozens of more or less abandoned projects that aren't usable with latest compilers anymore, - furthermore many users tend to maintaining their own fork rather than contributing to the project, thus useful functionality is often spread and sometimes even unknown cause the fork isn't publicly available - lack of IDEs, Descent is pretty good (and the only one regularly updated), but still has a long way to go. It's only reasonably usable with dsss, but rebuild is horribly outdated and always gets trapped in an infinite loop when using D2 and sometimes also refuses to work with D1. xf.build is still in the early stages and using the compiler directly is out of question. The newly added -deps parameter is probably a step forward, but wouldn't it be possible to simply include that rebuild functionality in dmd? I mean if it is possible to scan the dependencies and write them to a file, it shouldn't be that hard to simply add those found modules to the "working queue", should it? Build tools could then concentrate on the stuff dsss actually does like project management, installing and so on (which it does in a brilliant way imho, I really like the dsss.conf style)Much of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.This is EXACTLY the point I always try to make to newcomers. It's so significant that I think it should be on the front page of the language spec, in bold, 72 point, red letters.
Jul 22 2009
On Wed, Jul 22, 2009 at 3:59 PM, Jarrett Billingsley<jarrett.billingsley gmail.com> wrote:On Wed, Jul 22, 2009 at 6:30 PM, Walter Bright<newshound1 digitalmars.com> wrote:goMuch of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to=Yeh, it's like what's the big diff between a Lamborghini and a Chevy Nova anyway? They both have four tires. They both run on gas. So what's all the fuss about the Lamborghini? --bbback to another language.This is EXACTLY the point I always try to make to newcomers. =A0It's so significant that I think it should be on the front page of the language spec, in bold, 72 point, red letters.
Jul 22 2009
Bill Baxter wrote:Yeh, it's like what's the big diff between a Lamborghini and a Chevy Nova anyway? They both have four tires. They both run on gas. So what's all the fuss about the Lamborghini?It's like a car from the 60's vs a car today. It's hard to see what's really different, until you spend time driving one. There's just a boatload of little improvements in everything that add up to a lot. It's no surprise that most people who fix up those old cars also upgrade the systems with modern technology.
Jul 22 2009
Walter Bright wrote:Bill Baxter wrote:Or like driving an American car vs. a Japanese or European car. AndreiYeh, it's like what's the big diff between a Lamborghini and a Chevy Nova anyway? They both have four tires. They both run on gas. So what's all the fuss about the Lamborghini?It's like a car from the 60's vs a car today.
Jul 22 2009
On Wed, Jul 22, 2009 at 10:00 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Or like driving an American car vs. a Japanese or European car.Yeah, what *is* the deal with that? In terms of little convenience features, American cars feel outright primitive compared to Japanese and European cars.. Sorry for the OT :P
Jul 22 2009
Jarrett Billingsley wrote:On Wed, Jul 22, 2009 at 10:00 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Would you believe there is a guy in this newsgroup who'd manage to keep a straight face while saying that Ford is better designed than Mercedes? AndreiOr like driving an American car vs. a Japanese or European car.Yeah, what *is* the deal with that? In terms of little convenience features, American cars feel outright primitive compared to Japanese and European cars.. Sorry for the OT :P
Jul 22 2009
On Wed, Jul 22, 2009 at 6:49 PM, Walter Bright<newshound1 digitalmars.com> wrote:Bill Baxter wrote:oYeh, it's like what's the big diff between a Lamborghini and a Chevy Nova anyway? =A0They both have four tires. =A0They both run on gas. =A0S=llywhat's all the fuss about the Lamborghini?It's like a car from the 60's vs a car today. It's hard to see what's rea=different, until you spend time driving one. There's just a boatload of little improvements in everything that add up to a lot. It's no surprise that most people who fix up those old cars also upgrade =thesystems with modern technology.That's a better analogy. Or like the guy who works on my bicycle was telling me just this week before he got started trying to fix the thing I was complaining about. "In an ideal world every bike would be a $7000 bike." That's because basically everything is built to higher tolerances on a $7000 bike and everything just works exactly like it's supposed to. D is a lot like that $7000 bike -- except, thankfully, for the price tag. --bb
Jul 23 2009
Walter Bright wrote:It's no surprise that most people who fix up those old cars also upgrade the systems with modern technology.I was just over in one of the restoration forums, where they're talking about a company that makes exact reproductions of original wiring harnesses. Turns out they aren't exact reproductions, they're using much higher quality wire that is more resistant to heat.
Jul 23 2009
On Wed, Jul 22, 2009 at 06:59:45PM -0400, Jarrett Billingsley wrote:On Wed, Jul 22, 2009 at 6:30 PM, Walter Bright<newshound1 digitalmars.com> wrote:Agreed. This is the big benefit, but the hard part is that it takes some experience to really realize it. How can we sell that to someone who doesn't have that experience using it? "Just take my word for it" doesn't mean much when coming from strangers on the Internet, or from the site's homepage. -- Adam D. Ruppe http://arsdnet.netMuch of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.This is EXACTLY the point I always try to make to newcomers.
Jul 22 2009
On Wed, Jul 22, 2009 at 4:19 PM, Adam D. Ruppe<destructionator gmail.com> wrote:On Wed, Jul 22, 2009 at 06:59:45PM -0400, Jarrett Billingsley wrote:Even that does have a cumulative effect, though. If you keep hearing "take my word for it" from different sources, eventually, if you have any curiousity at all, you'll want to check it out for yourself. --bbOn Wed, Jul 22, 2009 at 6:30 PM, Walter Bright<newshound1 digitalmars.com> wrote:Agreed. This is the big benefit, but the hard part is that it takes some experience to really realize it. How can we sell that to someone who doesn't have that experience using it? "Just take my word for it" doesn't mean much when coming from strangers on the Internet, or from the site's homepage.Much of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.This is EXACTLY the point I always try to make to newcomers.
Jul 22 2009
Bill Baxter wrote:Even that does have a cumulative effect, though. If you keep hearing "take my word for it" from different sources, eventually, if you have any curiousity at all, you'll want to check it out for yourself.Right. Just keep making comments about D in public forums in appropriate contexts. It works. I give presentations on D frequently. I always start with: 1. Who has heard of D? 2. Who has written programs in D? Over time, the hands raised on (1) have gone from a few to essentially 100%. (2) is rising steadily.
Jul 22 2009
Walter Bright wrote:immutable - data that cannot change or be changed (imagine it is stored in ROM) const - read only view of data, you cannot change it but others can enum - compile time constant, has no storage The only place these overlap is in the declaration of symbolic constants. C++ has all three, but in a way that is context dependent that very few people are aware of.Aren't immutable and enum the same thing? At least to the programmer?But in C++ you can put a class object on the stack with value semantics, just as you can put a struct object on the heap. No problem, really. Stack is default. For the heap, all you need is a pointer. Personally I hate Java style reference semantics (a.k.a. heap without pointers). Especially because they also offer a small set of value types, to confuse matters. Now here's D doing the same thing. So the solution in D would then be to always use struct? No, because value semantics seems to come at the price of inheritance. Why? C++ seems to handle inheritance in value types just fine.* structs, classesstructs are value types, classes are reference types. That's a fundamental distinction, not two ways to do the same thing. A lot of confusing problems with C++ code stem from attempting to use a struct (or class!) both ways, or trying to give it characteristics of both.Actually, lazy parameter evaluation has its purpose. I personally like languages in which there are little or no "special constructs" that only the compiler can provide. In this case, lazy parameter eval could be used to overload your own short-circuiting operator.* functions, delegates, lazy parameter evaluationLazy parameter evaluation may turn out to be a bad idea, it doesn't seem to have found its "groove" anywhere. On the other hand, you can just ignore them like everyone else does, like everyone ignores exception specifications in C++.There's some undeniable extra complexity in having both function pointers and delegates. At some level, function pointers must be supported in order to support the C interface. Delegates are just too useful to give up (C++ has had awful problems trying to work around not having them - member function pointers anyone? Boost::bind? no thanks).I understand why you keep delegates around. I'd just call them function variables and remove the C(++) cruft. But D's goal is to keep some sort of backwards compatibility, so ok.Only when you're talking about optimization. There is great value in automatic proof of correctness. But I know this is a tall order.D offers some cool features, but leaves them very underpowered: * Contract programming (no contract inheritance, no compile-time static analysis, no loop invariants / ranking functions)True, but compile-time static analysis is a "quality of implementation" issue.Furthermore, I know of no language other than Eiffel that has all this, and nobody uses Eiffel.That's a spurious argument. The reason people don't use Eiffel is not its advanced contract programming features. (It may be the syntax.) Plus, you ignored the other points. Contract inheritance, loop invariants, ranking functions.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing. * No way to use +=, -=: I hope this one is clear. The operators that require both read and write access won't work on properties. * No global properties: If I'm not mistaken, global functions can't be properties. * No parameterized properties: c.f(5) = 6; // c.f(5, 6)* Class/Struct properties (no control over their use by class designer, no way to use +=, -=, no global properties, no parameterized properties)I don't understand what this means.Arithmetic like operations like matrix multiplication (which is not commutative)?* Operator overloading (no fine control over comparison operators,> fixed commutativity, This is deliberate. Operator overloading should be restricted to implementing arithmetic like operations on objects, not completely different things like what iostreams, Spirit and Boost::regex do.Perhaps you misunderstand. I was referring to the algorithm that first checks for a complete match, then tries the 'reverse overload', then tries the commutative call.confusing rule priority to determine translation,The alternative is "Koenig lookup", which I guarantee is far more confusing and has many weird problems.I can perhaps understand this one. Though I'm sure there are programmers that'd rather have the ability to overload it.no overloading of !, &&, ||,That's deliberate. For !, I wish to maintain the property of negation of the boolean result, as much of the semantics of transformation depend on it.For && and ||, they are "short circuit" operators, and how that would sensibly interact with operator overloading I have no idea.See my comments above about lazy parameter evaluation. I suggest that those operators are defined with a lazy second parameter for bools, and programmers should be allowed to overload them for other types as they please.I know of no language that allows overloading && and ||.C++ does. ! too.You cannot get a dedicated syntax with library support. I've mentioned I'm working on a programming language myself. I haven't mentioned its name here, because I didn't think it'd be appropriate. But with your permission I can post a link to a page describing my tuples.* Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples)The flattening thing is a problem. The rest can be done with better library support.Not unit testing, surely.* Unit testing (not at compile time,You can do testing at compile time with static asserts.> not possible to categorize) I agree that D's built-in unit testing is basic. But the fact that it exists *at all* is a huge improvement for a programming language. I firmly believe that its mere existence has been a big factor in improving the general quality of D code.Perhaps. But all these available but underpowered features make D look like a playground rather than a serious language. It's as if you think of a new feature, try it out for a week, then abandon it (I know, I'm exaggerating).The fact that you want more from unit testing is great. Unit testing has raised the bar of expectations on a language, and in that it's a home run.The fact that I want more, but you can't provide it, is a home run? :-)That was then, this is now. In the now, we have a C++ with classes and templates and a very strict standards committee overseeing its specification. You want to know why people in the now choose C++ over D? This is one reason.I maintain that D suffers greatly from its lack of a formal specification.Perhaps, but remember that most languages don't get formal specs until long after they become popular. Consider that C++ was defined by cfront for the first 10 or 12 years of its existence.Yes, but 'pretty clear' does not a spec make. I refer you to our earlier divide/modulo discussion. You expect programmers that want details to look at the DMD source code? And when you change a formal specification, people at least know the language changes as a result. When you change the compiler, we don't know if the language has changed or not. I know that most people can distinguish between a bug and a feature. But when you want to play with the big boys, you need to make it unambiguous.Not only does the D specification feel really unstable,I admit I'm not good at writing language lawyer text. But the D1 spec isn't unstable. The feature set is set, it's pretty clearMuch of D's improvements appear to be small, but the aggregate is large enough that once you write a project in D, you'll find it pretty hard to go back to another language.I don't dispute that most changes D has made to C++ are good, and that the result is greater than the sum of its parts. And if it weren't for all my other complaints, this one would not be enough to keep me from D. -- Michiel Helvensteijn
Jul 23 2009
Michiel Helvensteijn wrote:Walter Bright wrote:Well you can build an immutable list.immutable - data that cannot change or be changed (imagine it is stored in ROM) const - read only view of data, you cannot change it but others can enum - compile time constant, has no storage The only place these overlap is in the declaration of symbolic constants. C++ has all three, but in a way that is context dependent that very few people are aware of.Aren't immutable and enum the same thing? At least to the programmer?I think C++ does not handle inheritance in value types all that well, in fact the way it deals with the collision is pretty gruesome. It's all dark corners and dangers and caveats and puzzling behavior. There's only one place when anyone would seriously want something to be a value and a reference simultaneously, and that's exception classes. And those are tricky. I've never seen any correctly designed exception hierarchy in C++, starting with the standard exceptions. The fact that D requires one more allocation to throw an exception is IMHO a very small compromise. AndreiBut in C++ you can put a class object on the stack with value semantics, just as you can put a struct object on the heap. No problem, really. Stack is default. For the heap, all you need is a pointer. Personally I hate Java style reference semantics (a.k.a. heap without pointers). Especially because they also offer a small set of value types, to confuse matters. Now here's D doing the same thing. So the solution in D would then be to always use struct? No, because value semantics seems to come at the price of inheritance. Why? C++ seems to handle inheritance in value types just fine.* structs, classesstructs are value types, classes are reference types. That's a fundamental distinction, not two ways to do the same thing. A lot of confusing problems with C++ code stem from attempting to use a struct (or class!) both ways, or trying to give it characteristics of both.
Jul 23 2009
Andrei Alexandrescu wrote:Walter said something similar. I'm curious, which collision are you referring to? Which dark corners and dangers and caveats and puzzling behavior? Can you explain? Or perhaps refer me to a web location that explains? Thanks. -- Michiel HelvensteijnSo the solution in D would then be to always use struct? No, because value semantics seems to come at the price of inheritance. Why? C++ seems to handle inheritance in value types just fine.I think C++ does not handle inheritance in value types all that well, in fact the way it deals with the collision is pretty gruesome. It's all dark corners and dangers and caveats and puzzling behavior.
Jul 23 2009
Michiel Helvensteijn wrote:Andrei Alexandrescu wrote:The issues are discussed in the book C++ Coding Standards and also in More Effective C++. Part of the problem is slicing, which you may want to google for. MEC++ discusses the problem of defining constructors and particularly copy constructors in hierarchies. Assignment and comparison are also problematic. AndreiWalter said something similar. I'm curious, which collision are you referring to? Which dark corners and dangers and caveats and puzzling behavior? Can you explain? Or perhaps refer me to a web location that explains? Thanks.So the solution in D would then be to always use struct? No, because value semantics seems to come at the price of inheritance. Why? C++ seems to handle inheritance in value types just fine.I think C++ does not handle inheritance in value types all that well, in fact the way it deals with the collision is pretty gruesome. It's all dark corners and dangers and caveats and puzzling behavior.
Jul 23 2009
Andrei Alexandrescu wrote:The issues are discussed in the book C++ Coding Standards and also in More Effective C++. Part of the problem is slicing, which you may want to google for.I'm aware of slicing. I didn't really think of it as a problem. But now that you mention it, I suppose it can be confusing. And perhaps violate class invariants. There may be a solution. What I'm thinking now is that in the background, the heap may be used, as long as this is transparent to the programmer. i.e. assignment still makes a copy, comparison still compares the objects, not the addresses. But a base class value variable still has a superclass object in the background. This requires some thinking. Thanks for the clarification. -- Michiel Helvensteijn
Jul 23 2009
Andrei Alexandrescu wrote:The issues are discussed in the book C++ Coding Standards and also in More Effective C++. Part of the problem is slicing, which you may want to google for. MEC++ discusses the problem of defining constructors and particularly copy constructors in hierarchies. Assignment and comparison are also problematic.Yes, C++ has problems, but these problems can be fixed! The struct/class split, on the other hand, introduces many more problems that are harder to fix. -- Rainer Deyke - rainerd eldwood.com
Jul 23 2009
Rainer Deyke wrote:Andrei Alexandrescu wrote:How? Minding constantly a set of dangerous problems is not fixing it.The issues are discussed in the book C++ Coding Standards and also in More Effective C++. Part of the problem is slicing, which you may want to google for. MEC++ discusses the problem of defining constructors and particularly copy constructors in hierarchies. Assignment and comparison are also problematic.Yes, C++ has problems, but these problems can be fixed!The struct/class split, on the other hand, introduces many more problems that are harder to fix.Again: what are those problems? Andrei
Jul 23 2009
Andrei Alexandrescu wrote:Rainer Deyke wrote:Proposal 1: instances of polymorphic classes are stored on the heap but treated as value types. They are copied when the variable is copied (a full non-slicing copy), they are destroyed when the variable goes out of scope. In short, they are truly polymorphic value types, with some performance penalty. Proposal 2: Syntactically distinguish between polymorphic references (references to an instance of a class or any of its subclasses) and non-polymorphic references (references to an instance of a specific class and only that class), with the latter decaying to the former. Copy constructors would take a non-polymorphic reference as argument, thereby completely fixing the slicing problem.Yes, C++ has problems, but these problems can be fixed!How? Minding constantly a set of dangerous problems is not fixing it.Syntactic ambiguity. Confusion between an instance of a class and a reference to that instance. -- Rainer Deyke - rainerd eldwood.comThe struct/class split, on the other hand, introduces many more problems that are harder to fix.Again: what are those problems?
Jul 23 2009
Rainer Deyke wrote:I was initially thrown by this when I started some Java programming. But it soon became clear this was an advantage, and I came to prefer it. So I think this is a case of one's perspective, not an actual problem.Syntactic ambiguity. Confusion between an instance of a class and a reference to that instance.The struct/class split, on the other hand, introduces many more problems that are harder to fix.Again: what are those problems?
Jul 23 2009
Walter Bright wrote:Rainer Deyke wrote:I like it in Python, where all variables are references. Java is similar to Python in this regard, although the existence of primitive value types complicates the situation somewhat. I don't like it in D, where reference types and value types coexist. I especially don't like it in templates in D, where it may not be clear if you're dealing with a reference type or a value type until instantiation. -- Rainer Deyke - rainerd eldwood.comSyntactic ambiguity. Confusion between an instance of a class and a reference to that instance.I was initially thrown by this when I started some Java programming. But it soon became clear this was an advantage, and I came to prefer it.
Jul 23 2009
Rainer Deyke wrote:Walter Bright wrote:Is C++ really better in that regard? Given a non-trivial struct or class declaration, I'd be hard pressed to determine if it was meant to be a value or reference type.Rainer Deyke wrote:I like it in Python, where all variables are references. Java is similar to Python in this regard, although the existence of primitive value types complicates the situation somewhat. I don't like it in D, where reference types and value types coexist. I especially don't like it in templates in D, where it may not be clear if you're dealing with a reference type or a value type until instantiation.Syntactic ambiguity. Confusion between an instance of a class and a reference to that instance.I was initially thrown by this when I started some Java programming. But it soon became clear this was an advantage, and I came to prefer it.
Jul 23 2009
Walter Bright wrote:Rainer Deyke wrote:Yes, it is. Mainly because C++ doesn't have reference types in same way that D does. In C++, values of *all* types (including primitive integral types and even pointer types) can be placed on the heap, and such values are *always* managed by (smart) pointers, with pointer syntax. In this sense, all types in C++ can be used as reference types. There are C++ classes that are meant to always be placed on the heap and managed by a pointer. They are the closest C++ has to D-style classes. They are exceedingly rare. They're also easy to identify: their constructors are protected, so the only way to instantiate them is by calling a factory function that returns a (smart) pointer. -- Rainer Deyke - rainerd eldwood.comI like it in Python, where all variables are references. Java is similar to Python in this regard, although the existence of primitive value types complicates the situation somewhat. I don't like it in D, where reference types and value types coexist. I especially don't like it in templates in D, where it may not be clear if you're dealing with a reference type or a value type until instantiation.Is C++ really better in that regard? Given a non-trivial struct or class declaration, I'd be hard pressed to determine if it was meant to be a value or reference type.
Jul 24 2009
Rainer Deyke wrote:Yes, it is. Mainly because C++ doesn't have reference types in same way that D does. In C++, values of *all* types (including primitive integral types and even pointer types) can be placed on the heap, and such values are *always* managed by (smart) pointers, with pointer syntax. In this sense, all types in C++ can be used as reference types. There are C++ classes that are meant to always be placed on the heap and managed by a pointer. They are the closest C++ has to D-style classes. They are exceedingly rare. They're also easy to identify: their constructors are protected, so the only way to instantiate them is by calling a factory function that returns a (smart) pointer.A reference type isn't defined as one that only exists on the heap. Even in D, value types can be in the heap, and reference types can be on the stack. The value/reference dichotomy is how the object is referred to, not where it is.
Jul 24 2009
Rainer Deyke, el 23 de julio a las 19:49 me escribiste:Walter Bright wrote:!? It's true that in Python all are references, but there are inmutable objects in Python, like int, float, strings and tuples. From a practical POV it exactly the same as value types, if you do: def f(x, y): x = 5 y = (1, 3) a = 1 b = (5, 9) f(a, b) print a, b prints "1 (5, 9)", not "5 (1, 3)". So I can't see how you like Python's way and not D's way. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- En la calle me crucé con un señor muy correcto, que habitualmente anda en Falcon; iba corriendo con dos valijas en la mano y dijo: "Voy para Miami, tiene algún mensaje o ..." y le dije: "No, no, no..." -- Extra Tato (1983, Triunfo de Alfonsín)Rainer Deyke wrote:I like it in Python, where all variables are references. Java is similar to Python in this regard, although the existence of primitive value types complicates the situation somewhat. I don't like it in D, where reference types and value types coexist. I especially don't like it in templates in D, where it may not be clear if you're dealing with a reference type or a value type until instantiation.Syntactic ambiguity. Confusion between an instance of a class and a reference to that instance.I was initially thrown by this when I started some Java programming. But it soon became clear this was an advantage, and I came to prefer it.
Jul 24 2009
Leandro Lucarella wrote:!? It's true that in Python all are references, but there are inmutable objects in Python, like int, float, strings and tuples. From a practical POV it exactly the same as value types, if you do:Immutable reference types are still reference types, and follow the same rules as other reference types. You just can't modify them. The assignment operator *always* rebinds a reference, regardless of the mutability or immutability of any objects involved. The one exception is that operators like '+=' will create a new object when applied to immutable types, but modify existing objects when applied to mutable objects. And, yes, this bothers me in Python. A lot. But that's still not half as bad as D, where something simple like 'a = b; a.x = 5;' can have two completely different meanings depending on whether 'a' is a reference type or a value type. -- Rainer Deyke - rainerd eldwood.com
Jul 24 2009
Rainer Deyke wrote:Leandro Lucarella wrote:From a user's point of view, an immutable reference is indistinguishable from a value.!? It's true that in Python all are references, but there are inmutable objects in Python, like int, float, strings and tuples. From a practical POV it exactly the same as value types, if you do:Immutable reference types are still reference types, and follow the same rules as other reference types. You just can't modify them. The assignment operator *always* rebinds a reference, regardless of the mutability or immutability of any objects involved.But that's still not half as bad as D, where something simple like 'a = b; a.x = 5;' can have two completely different meanings depending on whether 'a' is a reference type or a value type.True. And in C++ with assignment overloads and copy constructors, one also has no clue what a.x=5 does without looking at the source to those functions. I don't think there's anyway we can pretend to know what semantics a type has in a language with user-definable types without at least looking at its declaration.
Jul 24 2009
Rainer Deyke, el 24 de julio a las 11:55 me escribiste:Leandro Lucarella wrote:That's true, conceptually, but when you use the variables, you use them as value types, with the same advantages and limitations.!? It's true that in Python all are references, but there are inmutable objects in Python, like int, float, strings and tuples. From a practical POV it exactly the same as value types, if you do:Immutable reference types are still reference types, and follow the same rules as other reference types. You just can't modify them. The assignment operator *always* rebinds a reference, regardless of the mutability or immutability of any objects involved.The one exception is that operators like '+=' will create a new object when applied to immutable types, but modify existing objects when applied to mutable objects. And, yes, this bothers me in Python. A lot.How do you note that? Really. Python inmutables have value semantics.But that's still not half as bad as D, where something simple like 'a = b; a.x = 5;' can have two completely different meanings depending on whether 'a' is a reference type or a value type.Yes, that's true, but this is a common problem. Think of operator overloading... Even in Python that could mean *anything* (__getattr__). -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Y será el día en que la electricidad deje de ser rayo y sea depilador femenino. -- Ricardo Vaporeso
Jul 24 2009
Leandro Lucarella wrote:Yes, that's true, but this is a common problem. Think of operator overloading... Even in Python that could mean *anything* (__getattr__).I want a programming language that enables me to write good code, not one that prevents me from writing bad code. Abusing operator overloading is bad code, and I try to avoid it. Using 'a = b; a.x = 5;' to mean two different things is also bad code, but it's not something I can avoid in D. -- Rainer Deyke - rainerd eldwood.com
Jul 24 2009
On Thu, Jul 23, 2009 at 12:11 PM, Rainer Deyke<rainerd eldwood.com> wrote:Yes, C++ has problems, but these problems can be fixed! =A0The struct/class split, on the other hand, introduces many more problems that are harder to fix.You know, this is like the first thing C++ users complain about on the IRC channel when they find D: "what if I want to turn a class into a struct, or vice versa?" I've been using D for five years, and I have never. EVER. Needed or desired to do that. Nor have I heard anyone but new C++ users complaining about it. Classes and structs are fundamentally different concepts. You design your code from the start to use one or the other, because only one makes sense.
Jul 23 2009
On Thu, 23 Jul 2009 13:10:59 -0400, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Thu, Jul 23, 2009 at 12:11 PM, Rainer Deyke<rainerd eldwood.com> wrote:I did. With dcollections, my nodes were classes at first, because they were supposed to be heap-allocated reference types. However, when I realized that with a custom allocator, I could tremendously increase performance, I had to switch to structs. What ended up happening is I simply aliased Node to node *, and that was that. Come to think of it, I probably didn't put enough thought in my choice of classes to begin with. This however, is not a true "change" since I just changed classes to struct references, not to actual value type structs. I plan on doing some more class-to-struct changes, not sure how it will pan out. But I think it certainly does come up that choosing struct or class is not an easy decision, and both can have advantages/disadvantages. However, I don't think C++ solves that problem very well either. The one thing I think is missing from D in this area is struct interfaces. -SteveYes, C++ has problems, but these problems can be fixed! The struct/class split, on the other hand, introduces many more problems that are harder to fix.You know, this is like the first thing C++ users complain about on the IRC channel when they find D: "what if I want to turn a class into a struct, or vice versa?" I've been using D for five years, and I have never. EVER. Needed or desired to do that. Nor have I heard anyone but new C++ users complaining about it.
Jul 23 2009
On Thu, Jul 23, 2009 at 1:20 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:However, when I realized that with a custom allocator, I could tremendously increase performance, I had to switch to structs.Um, did you? Because you can have custom allocators for classes too..
Jul 23 2009
Jarrett Billingsley, el 23 de julio a las 14:06 me escribiste:On Thu, Jul 23, 2009 at 1:20 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:And that reason only seems to be a complain with the GC performance, not with the struct/class separation ;) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Que barbaridad, este país se va cada ves más pa' tras, más pa' tras... -- Sidharta KiwiHowever, when I realized that with a custom allocator, I could tremendously increase performance, I had to switch to structs.Um, did you? Because you can have custom allocators for classes too..
Jul 23 2009
On Thu, 23 Jul 2009 14:06:12 -0400, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Thu, Jul 23, 2009 at 1:20 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:First, there were other reasons, such as I don't need polymorphism or interfaces for those node types, so switching to structs helped eliminate bloat for those features. What I did was allocate an array of structs vs. allocating each node, which uses the GC less. The less you use the GC the better when it comes to performance :) Can you do that with classes, I don't know. I thought it was impossible to allocate several classes in one block. It was pretty easy to do the custom allocator with structs... -SteveHowever, when I realized that with a custom allocator, I could tremendously increase performance, I had to switch to structs.Um, did you? Because you can have custom allocators for classes too..
Jul 23 2009
On Thu, Jul 23, 2009 at 3:13 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:Can you do that with classes, I don't know. =A0I thought it was impossibl=e toallocate several classes in one block. =A0It was pretty easy to do the cu=stomallocator with structs...Ah, that's a good point. It is in fact possible; you can use typeid(Class).classinfo.init.length to get the size of an instance at runtime, or with D2, __traits(classInstanceSize, Class) will get you the same thing, at compile time. Though your other reasons are certainly more than enough justification to move to structs (which, like you said, they probably should have been in the first place) :)
Jul 23 2009
Jarrett Billingsley wrote:Classes and structs are fundamentally different concepts. You design your code from the start to use one or the other, because only one makes sense.In my first (and to date only) D project, *all* my user-defined types started as structs, and *all* became classes when I found out that D1 structs don't support all of the features I need. (None of them used polymorphism. In C++, all would have been value types.) I expect the situation will be much better in D2. -- Rainer Deyke - rainerd eldwood.com
Jul 23 2009
On Thu, Jul 23, 2009 at 4:34 PM, Rainer Deyke<rainerd eldwood.com> wrote:Jarrett Billingsley wrote:And you don't think that has *anything* to do with trying to program C++ in= D.Classes and structs are fundamentally different concepts. =A0You design your code from the start to use one or the other, because only one makes sense.In my first (and to date only) D project, *all* my user-defined types started as structs, and *all* became classes when I found out that D1 structs don't support all of the features I need. =A0(None of them used polymorphism. =A0In C++, all would have been value types.)
Jul 23 2009
Jarrett Billingsley wrote:On Thu, Jul 23, 2009 at 4:34 PM, Rainer Deyke<rainerd eldwood.com> wrote:No, it was clearly a case of trying to program D2 in D1. In D2, all of these types should be structs. -- Rainer Deyke - rainerd eldwood.comIn my first (and to date only) D project, *all* my user-defined types started as structs, and *all* became classes when I found out that D1 structs don't support all of the features I need. (None of them used polymorphism. In C++, all would have been value types.)And you don't think that has *anything* to do with trying to program C++ in D.
Jul 23 2009
Michiel Helvensteijn wrote:Aren't immutable and enum the same thing? At least to the programmer?Not at all. How would you declare a type that is "pointer to immutable int" using an enum? Anyhow, there was a looong thread about this a year back or so.It may indeed be the syntax, but consider that no other language adopted those constructs. There was a proposal to add contracts to C++0x which died. I added them to Digital Mars C++ and nobody cared.Only when you're talking about optimization. There is great value in automatic proof of correctness. But I know this is a tall order.* Contract programming (no contract inheritance, no compile-time static analysis, no loop invariants / ranking functions)True, but compile-time static analysis is a "quality of implementation" issue.Furthermore, I know of no language other than Eiffel that has all this, and nobody uses Eiffel.That's a spurious argument. The reason people don't use Eiffel is not its advanced contract programming features. (It may be the syntax.)Plus, you ignored the other points. Contract inheritance, loop invariants, ranking functions.Contracts didn't hit paydirt, and so haven't gotten a lot of follow-on attention. Eiffel has contract inheritance, I think it has loop invariants, and I never heard of ranking functions.Why not? Seriously, what is the semantic difference?Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.* Class/Struct properties (no control over their use by class designer, no way to use +=, -=, no global properties, no parameterized properties)I don't understand what this means.* No way to use +=, -=: I hope this one is clear. The operators that require both read and write access won't work on properties.Agreed that's a problem. Andrei has also been a strong advocate of fixing it.* No global properties: If I'm not mistaken, global functions can't be properties.int foo() { return 3; } void main() { int x = foo; } works.* No parameterized properties: c.f(5) = 6; // c.f(5, 6)Ok.I believe this is completely controllable with D.Arithmetic like operations like matrix multiplication (which is not commutative)?* Operator overloading (no fine control over comparison operators,> fixed commutativity, This is deliberate. Operator overloading should be restricted to implementing arithmetic like operations on objects, not completely different things like what iostreams, Spirit and Boost::regex do.I did understand it. The alternative is Koenig Lookup, and the reason for its existence. Reverse operator overloading is a bit awkward, but the awkwardness is restricted to the class in which it appears. ADL (Koenig Lookup) spreads awkwardness everywhere.Perhaps you misunderstand. I was referring to the algorithm that first checks for a complete match, then tries the 'reverse overload', then tries the commutative call.confusing rule priority to determine translation,The alternative is "Koenig lookup", which I guarantee is far more confusing and has many weird problems.I'm sure there are, too. That doesn't mean it's a good idea! Features ought to have compelling use cases for them, not just it-would-be-nice-if.I can perhaps understand this one. Though I'm sure there are programmers that'd rather have the ability to overload it.no overloading of !, &&, ||,That's deliberate. For !, I wish to maintain the property of negation of the boolean result, as much of the semantics of transformation depend on it.Oops, you're right. Here's an old thread about it: http://www.digitalmars.com/d/archives/digitalmars/D/18153.html I can't recall ever seeing anyone use it, though. Until there's a compelling use case for it, not just it being a nice idea, I'll stick with my belief it's a bad idea.For && and ||, they are "short circuit" operators, and how that would sensibly interact with operator overloading I have no idea.See my comments above about lazy parameter evaluation. I suggest that those operators are defined with a lazy second parameter for bools, and programmers should be allowed to overload them for other types as they please.I know of no language that allows overloading && and ||.C++ does. ! too.Of course that's true, but why is a dedicated syntax better than Tuple!( ...) ?You cannot get a dedicated syntax with library support.* Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples)The flattening thing is a problem. The rest can be done with better library support.I've mentioned I'm working on a programming language myself. I haven't mentioned its name here, because I didn't think it'd be appropriate. But with your permission I can post a link to a page describing my tuples.Sure.You can use static asserts to, at compile time, check the result of any computation, including function calls, that the compiler is able to execute at compile time. It sounds perfectly usable as unit tests to me, and in fact I do use static assert that way.Not unit testing, surely.* Unit testing (not at compile time,You can do testing at compile time with static asserts.Perhaps. But all these available but underpowered features make D look like a playground rather than a serious language. It's as if you think of a new feature, try it out for a week, then abandon it (I know, I'm exaggerating).I replied more on unit testing in another response in this thread.Yes, but 'pretty clear' does not a spec make. I refer you to our earlier divide/modulo discussion.We're going to fix the modulo thing. But the C++ standard leaves it implementation defined. How is that better? And how about the C++ source character set and the behavior of "char"? It's a standardized specifying of a mess of implementation defined and undefined behavior. Sure, the D spec has gaps in it. But the C++ standard also has large gaps of uselessness in it.
Jul 23 2009
On Thu, 23 Jul 2009 15:11:07 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Michiel Helvensteijn wrote:It leads to making things look like properties when they are not. For example, writefln = "hi"; The worst is the assign statement, since there are plenty of legitimate uses of having a single argument function not actually assign anything. It can also lead to ambiguities, such as a property that returns a delegate must be called with double parens: c.member()(); It has nothing to do with how the compiler looks at it semantically, but it has everything to do with how the user reads it. I want the compiler to tell the user "no you can't use that member that way." so I don't get complaints that my "properties" are badly implemented (and yes, I've had this happen, see http://www.dsource.org/projects/tango/ticket/1184) property it's: int x { get { return _x; } set { _x = value; } // value is a context keyword } With D properties, x() and x(int value) could be scattered anywhere in the class. Notice also, that I can document x as a property, not as it's individual functions.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?Ugh, don't do this. You can implement this behavior easily enough. We already have opIndexAssign. -Steve* No parameterized properties: c.f(5) = 6; // c.f(5, 6)Ok.
Jul 23 2009
Walter Bright wrote:Michiel Helvensteijn wrote:Semantic difference: a property doesn't have *visible* side effects. If you invoke it one hundred times, it should always return the same thing. And nothing else in your program should change. So it's kind of like pure functions. I say "visible" because you might want to implement a property lazily. But the logic remains inside your class and it's visible in the outside world.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?
Jul 23 2009
Ary Borenszweig wrote:Walter Bright wrote:Ok, but not having visible side effects is just a convention, one which is apparently not enforced by languages with special property syntax. A pure function, however, can be statically guaranteed to have no side effects. So IDEs, etc., can regard as 'properties' any such methods which take no arguments.Michiel Helvensteijn wrote:Semantic difference: a property doesn't have *visible* side effects. If you invoke it one hundred times, it should always return the same thing. And nothing else in your program should change. So it's kind of like pure functions. I say "visible" because you might want to implement a property lazily. But the logic remains inside your class and it's visible in the outside world.* No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?
Jul 23 2009
Walter Bright wrote:Ary Borenszweig wrote:That's true, but you haven't addressed the other side of it: property setters. Let me give you an example of where I think a few people are trying to come from. In VB6, you could create custom ActiveX controls. In the code for it, you could declare properties with getters and setters. The nice thing was that because the IDE could tell the difference between functions and properties, it could display these properties automatically in the property sheet for each control. With D, you would need to explicitly state which methods are properties manually somehow; dunno how you would, though. Especially when you consider subclassing and mixins.Walter Bright wrote:Ok, but not having visible side effects is just a convention, one which is apparently not enforced by languages with special property syntax. A pure function, however, can be statically guaranteed to have no side effects. So IDEs, etc., can regard as 'properties' any such methods which take no arguments.Michiel Helvensteijn wrote:Semantic difference: a property doesn't have *visible* side effects. If you invoke it one hundred times, it should always return the same thing. And nothing else in your program should change. So it's kind of like pure functions. I say "visible" because you might want to implement a property lazily. But the logic remains inside your class and it's visible in the outside world.* No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?
Jul 23 2009
Daniel Keep wrote:That's true, but you haven't addressed the other side of it: property setters.Right. Consider the case where there's a pure function with no arguments, and an overload with the same name and one argument, and no other overloads. Wouldn't it be reasonable to take that as a property setter?With D, you would need to explicitly state which methods are properties manually somehow; dunno how you would, though. Especially when you consider subclassing and mixins.See my rule above - I think it'll work.
Jul 23 2009
Walter Bright wrote:Daniel Keep wrote:Actually, I've now come up with a counter-example for the idea of using pure at all: class Lazy(T) { private { T v; T delegate() dg; } this(T delegate() dg) { this.dg = dg; } T value() { if( dg !is null ) { v = dg(); dg = null; } return v; } } You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!That's true, but you haven't addressed the other side of it: property setters.Right. Consider the case where there's a pure function with no arguments, and an overload with the same name and one argument, and no other overloads. Wouldn't it be reasonable to take that as a property setter?With D, you would need to explicitly state which methods are properties manually somehow; dunno how you would, though. Especially when you consider subclassing and mixins.See my rule above - I think it'll work.
Jul 24 2009
Daniel Keep escribió:Walter Bright wrote:Exactly! That's why I said "kind of pure" (well, maybe I didn't say that :-P), but the idea is that properties don't modify anything visible from outside of the symbol they are contained in. But it's hard to define what that means...Daniel Keep wrote:Actually, I've now come up with a counter-example for the idea of using pure at all: class Lazy(T) { private { T v; T delegate() dg; } this(T delegate() dg) { this.dg = dg; } T value() { if( dg !is null ) { v = dg(); dg = null; } return v; } } You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!That's true, but you haven't addressed the other side of it: property setters.Right. Consider the case where there's a pure function with no arguments, and an overload with the same name and one argument, and no other overloads. Wouldn't it be reasonable to take that as a property setter?With D, you would need to explicitly state which methods are properties manually somehow; dunno how you would, though. Especially when you consider subclassing and mixins.See my rule above - I think it'll work.
Jul 24 2009
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:h4br9n$1rje$1 digitalmars.com...You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!Speaking of that, has my top-level post about that (Subject: "DIP4: Properties") shown up for anyone? I first posted it about 12:30am (my time, 4.5 hours ago), than again between 1 and 2, and again just now, and none of them are showing up for me. I know there can be a delay, but I've never had more than a few seconds of delay on here before for a top-level or for a reply.
Jul 24 2009
"Nick Sabalausky" <a a.a> wrote in message news:h4bt95$1uul$1 digitalmars.com..."Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:h4br9n$1rje$1 digitalmars.com...My stuff seems to still be showing up fine in this thread...You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!Speaking of that, has my top-level post about that (Subject: "DIP4: Properties") shown up for anyone? I first posted it about 12:30am (my time, 4.5 hours ago), than again between 1 and 2, and again just now, and none of them are showing up for me. I know there can be a delay, but I've never had more than a few seconds of delay on here before for a top-level or for a reply.
Jul 24 2009
Nick Sabalausky wrote:"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:h4br9n$1rje$1 digitalmars.com...I can see three posts by you in the DIP4 thread. -LarsYou can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!Speaking of that, has my top-level post about that (Subject: "DIP4: Properties") shown up for anyone? I first posted it about 12:30am (my time, 4.5 hours ago), than again between 1 and 2, and again just now, and none of them are showing up for me. I know there can be a delay, but I've never had more than a few seconds of delay on here before for a top-level or for a reply.
Jul 24 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> wrote in message news:h4bua5$20bd$1 digitalmars.com...Nick Sabalausky wrote:Strange, I still can't see the thread at all, and I've never had trouble seeing my own posts (even in this thread). I'm at least relieved that it apperently isn't three separate DIP4 threads :) Is there a post by anyone other than me in that thread? If not, maybe that would get my reader to finally wake up."Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:h4br9n$1rje$1 digitalmars.com...I can see three posts by you in the DIP4 thread.You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!Speaking of that, has my top-level post about that (Subject: "DIP4: Properties") shown up for anyone? I first posted it about 12:30am (my time, 4.5 hours ago), than again between 1 and 2, and again just now, and none of them are showing up for me. I know there can be a delay, but I've never had more than a few seconds of delay on here before for a top-level or for a reply.
Jul 24 2009
Nick Sabalausky wrote:"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> wrote in message news:h4bua5$20bd$1 digitalmars.com...Actually, on closer inspection, it turns out there are three separate DIP4 threads. Apparently, Thunderbird was smart enough to group them for me. :)Nick Sabalausky wrote:Strange, I still can't see the thread at all, and I've never had trouble seeing my own posts (even in this thread). I'm at least relieved that it apperently isn't three separate DIP4 threads :)"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message news:h4br9n$1rje$1 digitalmars.com...I can see three posts by you in the DIP4 thread.You can't make value pure, but it is supposed to be a property. One of the examples Nick gives in DIP4 is a property that accesses an SQL database; there's no way to make that pure!Speaking of that, has my top-level post about that (Subject: "DIP4: Properties") shown up for anyone? I first posted it about 12:30am (my time, 4.5 hours ago), than again between 1 and 2, and again just now, and none of them are showing up for me. I know there can be a delay, but I've never had more than a few seconds of delay on here before for a top-level or for a reply.Is there a post by anyone other than me in that thread? If not, maybe that would get my reader to finally wake up.Yes, Daniel Keep has posted two replies. PS: Both his and your messages are visible in the web interface. -Lars
Jul 24 2009
Daniel Keep wrote:Actually, I've now come up with a counter-example for the idea of using pure at all:That's right, lazy evaluation can't be pure. So, the question is is this an important enough case to justify a whole new syntax?
Jul 24 2009
On Fri, 24 Jul 2009 13:37:16 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Daniel Keep wrote:Don't get lost in the pure discussion. There are many reasons to have a dedicated property syntax, even for non-pure properties. I don't think properties should be necessarily pure anyways. How do you have a pure setter? It's more of a convention that a property getter should not change the state of the containing entity, a pretty much non-enforcable convention. That's not to say that you couldn't mark a property as const or pure, just that it shouldn't HAVE to be that way. -SteveActually, I've now come up with a counter-example for the idea of using pure at all:That's right, lazy evaluation can't be pure. So, the question is is this an important enough case to justify a whole new syntax?
Jul 24 2009
Steven Schveighoffer wrote:I don't think properties should be necessarily pure anyways. How do you have a pure setter? It's more of a convention that a property getter should not change the state of the containing entity, a pretty much non-enforcable convention.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.
Jul 24 2009
On Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Steven Schveighoffer wrote:If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person. It's the exact same reason + is not the concatenation operator. Semantically, making + concatenate two strings together would be completely unambiguous from adding two integers together because strings do not define addition, and integers do not define concatenation. From your own documentation, someone seeing "10" + 3 might think that he would get 13 or "103". Even if the compiler defines what "should" happen, and the rules are unambiguous, it looks incorrect to the user. But having ~ be the concatenation operator makes it completely unambiguous what the syntax means, regardless of what the types are. So the compiler and the user are talking the same language, and the user isn't freaked out by the "human meaning" of the syntax. -SteveI don't think properties should be necessarily pure anyways. How do you have a pure setter? It's more of a convention that a property getter should not change the state of the containing entity, a pretty much non-enforcable convention.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.
Jul 24 2009
Steven Schveighoffer wrote:On Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Maybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like: int property foo(); // getter int property foo(int value); // setter So properties are marked with a modifier and that's it. The compiler could discard those modifiers or, much better, disallow doing things like: bar = 3; // ERROR: bar is not a property foo(); // ERROR: foo is a property and must be used as foo Now we need someone to think which of the current keywords could be used instead of "property". :-PSteven Schveighoffer wrote:If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person. It's the exact same reason + is not the concatenation operator. Semantically, making + concatenate two strings together would be completely unambiguous from adding two integers together because strings do not define addition, and integers do not define concatenation. From your own documentation, someone seeing "10" + 3 might think that he would get 13 or "103". Even if the compiler defines what "should" happen, and the rules are unambiguous, it looks incorrect to the user. But having ~ be the concatenation operator makes it completely unambiguous what the syntax means, regardless of what the types are. So the compiler and the user are talking the same language, and the user isn't freaked out by the "human meaning" of the syntax. -SteveI don't think properties should be necessarily pure anyways. How do you have a pure setter? It's more of a convention that a property getter should not change the state of the containing entity, a pretty much non-enforcable convention.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.
Jul 24 2009
On Fri, 24 Jul 2009 15:12:10 -0400, Ary Borenszweig <ary esperanto.org.ar> wrote:Maybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like:His point is that there are no benefits to the semantic meaning of the code by declaring something a property. It's still a function, still gets implemented by a function. It's like if you say functions can now be called like this: foo^arg But he's not getting that the compiler isn't the only one reading the code, and D isn't the only language being used. You are also using a person's knowledge of math (x = y) and a person's native language. At least the native language, the compiler knows and cares nothing about, but the developer and user care greatly (and want the conventions enforced). -Steve
Jul 24 2009
On Fri, Jul 24, 2009 at 12:21 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:On Fri, 24 Jul 2009 15:12:10 -0400, Ary Borenszweig <ary esperanto.org.ar= wrote:stMaybe what scares Walter is a whole new syntax for properties. If at lea=ldyou could say which functions are properties and which are not, that wou=debe a small change and it'll make it possible for other things. Something like:His point is that there are no benefits to the semantic meaning of the co=by declaring something a property. =A0It's still a function, still gets implemented by a function. It's like if you say functions can now be called like this: foo^arg But he's not getting that the compiler isn't the only one reading the cod=e,and D isn't the only language being used. =A0You are also using a person'=sknowledge of math (x =3D y) and a person's native language. =A0At least t=henative language, the compiler knows and cares nothing about, but the developer and user care greatly (and want the conventions enforced).Another example: arrays are just functions too. So there's no real need for a distinct a[i] syntax. a(i) would work just fine (and is exactly what's used in Fortran and Matlab for array indexing). But we kind of like being able to see right away that something is intended to be indexing. It give the reader of the code a hint about the intended semantics. But of course the compiler can't enforce that every opIndex overload conforms to that. You could write an opIndex overload that prints to stdout. But generally people don't do that because that would be sending the wrong signal. Generally the opIndex overloads offer index-ing like behavior. --bb
Jul 24 2009
Ary Borenszweig wrote:Maybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 24 2009
On 2009-07-24 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> said:It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.You know. I agree with you on that point. Earlier, in a thread no one replied to [1], demonstrated that we already have almost everyting we need to create properties using mixins. Here's an example: struct Z { int valueSquare; template Property() { int value; void opAssign(int v) { value = v; valueSquare = value * value; } void opAddAssign(int v) { value = v; valueSquare = value * value; } int get() { return value; } alias get this; } mixin Property property; } The only really missing part is that "alias get this" doesn't work ("Error: expression has no value" when fetching a value from z.property) so you have to explicitly call the "get" function. [1]: http://www.digitalmars.com/d/archives/digitalmars/D/properties_using_template_mixins_and_alias_this_87952.html -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 24 2009
On Fri, 24 Jul 2009 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Ary Borenszweig wrote:OK, so you don't like the idea of adding dedicated properties. What is *your* solution to forbidding abuses like this: writefln = "hi"; ??? -SteveMaybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 27 2009
On Mon, Jul 27, 2009 at 7:13 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:On Fri, 24 Jul 2009 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> wrote:I think his suggestion was the Java-style approach -- special naming convention for get/set functions: int opGet_foo() { return foo_; } void opSet_foo(int foo) { foo_ = foo; } private: int foo_; --bbAry Borenszweig wrote:OK, so you don't like the idea of adding dedicated properties. What is *your* solution to forbidding abuses like this: writefln = "hi"; ???Maybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 27 2009
On Mon, 27 Jul 2009 13:23:42 -0400, Bill Baxter <wbaxter gmail.com> wrote:On Mon, Jul 27, 2009 at 7:13 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:Really? I got the impression that he does not think properties warrant any kind of special syntax. If that's the solution it's ok with me, the only issue is name collision (as others have mentioned): int opGet_foo() int foo; must be forbidden. This is different from other opX operators since the true names of those operators cannot be symbols, and therefore could never have collisions. -SteveOn Fri, 24 Jul 2009 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> wrote:I think his suggestion was the Java-style approach -- special naming convention for get/set functions: int opGet_foo() { return foo_; } void opSet_foo(int foo) { foo_ = foo; } private: int foo_;Ary Borenszweig wrote:OK, so you don't like the idea of adding dedicated properties. What is *your* solution to forbidding abuses like this: writefln = "hi"; ???Maybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 27 2009
Bill Baxter wrote:On Mon, Jul 27, 2009 at 7:13 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:For one thing I like that I now get to define empty() for a range and then call it with r.empty. I'd think it would be a small step backward if I had to define get_empty() or something instead. AndreiOn Fri, 24 Jul 2009 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> wrote:I think his suggestion was the Java-style approach -- special naming convention for get/set functions: int opGet_foo() { return foo_; } void opSet_foo(int foo) { foo_ = foo; } private: int foo_; --bbAry Borenszweig wrote:OK, so you don't like the idea of adding dedicated properties. What is *your* solution to forbidding abuses like this: writefln = "hi"; ???Maybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 27 2009
On Mon, 27 Jul 2009 13:59:53 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:The "getter" notation that currently exists only has a few minor problems. The most major of those problems is if the return value is a callable type, such as a delegate, you can't easily perform the call on the returned value. Being that it isn't very bad for the getter property, would it make sense to leave that functionality? That is: 1. A setter must be defined in the opSet_X(int x) form 2. A getter can be a function with no required arguments, but this getter should not return callable types 3. A getter can be defined in the opGet_X() form, and then using X() will be the eqivalent of opGet_X()(). There are small implications to leaving the existing getter syntax. Namely one can call a function not intended to be a getter in a property-like syntax, resulting in less-than-obvious code. Also, this distinction will be very hard to explain to newbies ("how come a getter is defined as x(), but a setter has to be opSet_x(...)?). The more I look at it, the more I like the keyword solution. I do find you only absolutely need that if you are going to have context-keywords, properties tedious to type. With a keyword attribute, you could even group your properties together to save on typing/ugliness: property { int x() {} void x(int n) {} bool empty() {} } -SteveOn Mon, Jul 27, 2009 at 7:13 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:For one thing I like that I now get to define empty() for a range and then call it with r.empty. I'd think it would be a small step backward if I had to define get_empty() or something instead.On Fri, 24 Jul 2009 17:40:37 -0400, Walter Bright <newshound1 digitalmars.com> wrote:I think his suggestion was the Java-style approach -- special naming convention for get/set functions: int opGet_foo() { return foo_; } void opSet_foo(int foo) { foo_ = foo; } private: int foo_; --bbAry Borenszweig wrote:OK, so you don't like the idea of adding dedicated properties. What is *your* solution to forbidding abuses like this: writefln = "hi"; ???Maybe what scares Walter is a whole new syntax for properties.It doesn't scare me. It's trivial to add more syntax. It's just that D is complex enough - there needs to be some very good reasons for adding more syntax that has apparently zero semantic information that would be different from the usual function syntax.
Jul 27 2009
Steven Schveighoffer:property { int x() {} void x(int n) {} bool empty() {} }An alternative: property(x) { ... // or getter and/or setter } Bye, bearophile
Jul 27 2009
On Mon, 27 Jul 2009 15:30:17 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:No, that is a different proposal. All I was saying is if property is an attribute, then like other attributes (const, etc), code like this: property int x() {} property void x(int n) {} property bool empty() {} can be rewritten as above. -Steveproperty { int x() {} void x(int n) {} bool empty() {} }An alternative: property(x) { ... // or getter and/or setter }
Jul 27 2009
Steven Schveighoffer wrote:The "getter" notation that currently exists only has a few minor problems. The most major of those problems is if the return value is a callable type, such as a delegate, you can't easily perform the call on the returned value.Thanks for a very lucid analysis! So let me give an example: class A { int delegate() wyda() { return delegate int() { return 5; }; } } void main(string[] args) { auto a = new A; auto b = a.wyda; writeln(typeof(b).stringof); auto c = a.wyda(); writeln(typeof(c).stringof); auto d = a.wyda()(); writeln(typeof(d).stringof); auto e = &a.wyda; writeln(typeof(e).stringof); } This program prints: int delegate() int delegate() int int delegate() delegate() I agree that that's an issue. One can't currently implement transparently a property that returns a delegate taking no arguments. There's an extra () needed.Being that it isn't very bad for the getter property, would it make sense to leave that functionality? That is: 1. A setter must be defined in the opSet_X(int x) form 2. A getter can be a function with no required arguments, but this getter should not return callable types... with zero arguments.3. A getter can be defined in the opGet_X() form, and then using X() will be the eqivalent of opGet_X()(). There are small implications to leaving the existing getter syntax. Namely one can call a function not intended to be a getter in a property-like syntax, resulting in less-than-obvious code.This I don't agree with. I am very happy that I define popFront() as a method and then call it without parens.Also, this distinction will be very hard to explain to newbies ("how come a getter is defined as x(), but a setter has to be opSet_x(...)?).I don't see that as a problem. You just explain that the trailing () is not necessary, and then you tell them to define opSet_x if they want to enable obj.x = y.The more I look at it, the more I like the keyword solution. I do find think you only absolutely need that if you are going to have context-keywords, which I DON'T think we need. I do find the whole With a keyword attribute, you could even group your properties together to save on typing/ugliness: property { int x() {} void x(int n) {} bool empty() {} }Not a fan, but this would work. I just don't see why I need to go through with it. Andrei
Jul 27 2009
Andrei Alexandrescu Wrote:Steven Schveighoffer wrote:Hi, I'm new here. A simple idea I've had is to simply use aliases for defining properties. If you allow writing aliases as expressions, you have get properties. Then a simple extension to the syntax would also allow for writing set properties. alias (a) property; alias (a = n) property(n); foo(property); // Get property = 32; // Set This virtually eliminates any problems with properties, and it doesn't require any new keywords. It won't break existing aliases either.The "getter" notation that currently exists only has a few minor problems. The most major of those problems is if the return value is a callable type, such as a delegate, you can't easily perform the call on the returned value.Thanks for a very lucid analysis! So let me give an example: class A { int delegate() wyda() { return delegate int() { return 5; }; } } void main(string[] args) { auto a = new A; auto b = a.wyda; writeln(typeof(b).stringof); auto c = a.wyda(); writeln(typeof(c).stringof); auto d = a.wyda()(); writeln(typeof(d).stringof); auto e = &a.wyda; writeln(typeof(e).stringof); } This program prints: int delegate() int delegate() int int delegate() delegate() I agree that that's an issue. One can't currently implement transparently a property that returns a delegate taking no arguments. There's an extra () needed.Being that it isn't very bad for the getter property, would it make sense to leave that functionality? That is: 1. A setter must be defined in the opSet_X(int x) form 2. A getter can be a function with no required arguments, but this getter should not return callable types... with zero arguments.3. A getter can be defined in the opGet_X() form, and then using X() will be the eqivalent of opGet_X()(). There are small implications to leaving the existing getter syntax. Namely one can call a function not intended to be a getter in a property-like syntax, resulting in less-than-obvious code.This I don't agree with. I am very happy that I define popFront() as a method and then call it without parens.Also, this distinction will be very hard to explain to newbies ("how come a getter is defined as x(), but a setter has to be opSet_x(...)?).I don't see that as a problem. You just explain that the trailing () is not necessary, and then you tell them to define opSet_x if they want to enable obj.x = y.The more I look at it, the more I like the keyword solution. I do find think you only absolutely need that if you are going to have context-keywords, which I DON'T think we need. I do find the whole With a keyword attribute, you could even group your properties together to save on typing/ugliness: property { int x() {} void x(int n) {} bool empty() {} }Not a fan, but this would work. I just don't see why I need to go through with it. Andrei
Jul 27 2009
On Mon, Jul 27, 2009 at 7:33 PM, escalan<escalan gmail.com> wrote:Hi, I'm new here. A simple idea I've had is to simply use aliases for defining properties. If you allow writing aliases as expressions, you have get properties. Then a simple extension to the syntax would also allow for writing set properties. alias (a) property; alias (a = n) property(n); foo(property); // Get property = 32; // Set This virtually eliminates any problems with properties, and it doesn't require any new keywords. It won't break existing aliases either.Except if you want to do anything more complex in your setter/getter than a simple expression.
Jul 27 2009
On Mon, Jul 27, 2009 at 7:49 PM, Jarrett Billingsley<jarrett.billingsley gmail.com> wrote:On Mon, Jul 27, 2009 at 7:33 PM, escalan<escalan gmail.com> wrote:Also, if your suggestion really did just replace any accesses to the property with the aliased expression, there would be no way to override it in subclasses, it would be invisible to the debugger, etc.Hi, I'm new here. A simple idea I've had is to simply use aliases for defining properties. If you allow writing aliases as expressions, you have get properties. Then a simple extension to the syntax would also allow for writing set properties. alias (a) property; alias (a = n) property(n); foo(property); // Get property = 32; // Set This virtually eliminates any problems with properties, and it doesn't require any new keywords. It won't break existing aliases either.Except if you want to do anything more complex in your setter/getter than a simple expression.
Jul 27 2009
On Mon, 27 Jul 2009 18:37:01 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:You're welcome :)The "getter" notation that currently exists only has a few minor problems. The most major of those problems is if the return value is a callable type, such as a delegate, you can't easily perform the call on the returned value.Thanks for a very lucid analysis!No, callable types period. Note that this does not compile: class A { int delegate(int foo) wyda() { return delegate int(int foo) { return foo;}; } } int main(string[] args) { auto a = new A; auto b = a.wyda(5); // line 14 auto c = a.wyda()(5); return 1; } [steves steveslaptop files]$ dmd testme.d testme.d(14): Error: function testme.A.wyda () does not match parameter types (int) testme.d(14): Error: expected 0 arguments, not 1 commenting out line 14 compiles.Being that it isn't very bad for the getter property, would it make sense to leave that functionality? That is: 1. A setter must be defined in the opSet_X(int x) form 2. A getter can be a function with no required arguments, but this getter should not return callable types... with zero arguments.Knowing that you can call functions without parens, seeing code like: r.popFront; it's obvious that popFront is a function, not a property. But, do you agree that this code looks less-than-obvious? auto x = flush; is flush a flag saying flushing should occur? is it a function that flushes something, and returns the success? I agree that the bizarre factor is not as bad as with setters, but it's still not as self-explanatory as if you know that something without parens must be a property for the compiler to accept it. Also, without a dedicated property syntax for setters, you have the problem mentioned above with callable types. At the very least you need the alternate syntax, the automagic properties for zero-arg functions are optional.3. A getter can be defined in the opGet_X() form, and then using X() will be the eqivalent of opGet_X()(). There are small implications to leaving the existing getter syntax. Namely one can call a function not intended to be a getter in a property-like syntax, resulting in less-than-obvious code.This I don't agree with. I am very happy that I define popFront() as a method and then call it without parens.Perhaps. I admit that I don't have any real evidence to support my claim, but I don't think you do either ;)Also, this distinction will be very hard to explain to newbies ("how come a getter is defined as x(), but a setter has to be opSet_x(...)?).I don't see that as a problem. You just explain that the trailing () is not necessary, and then you tell them to define opSet_x if they want to enable obj.x = y.Let's separate this problem into two sections: 1. do we have to hint to the compiler that a function is a property or not? I think we do, otherwise, we have the strange setter anomalies, and the inability to return delegates from getters. If you think this is not the case, state your arguments and solutions to those problems. I don't think the compiler can tell if something is meant to be a property or not by looking at it. hints be? This is more of a bikeshed issue, but there are some technical issues to consider (- = negative, + = positive): For an opSet style syntax (e.g. int opSet_foo()): - There is a possible conflict between opSet_foo and foo. Since it would be the only operator function where the calling syntax is also valid symbol. i.e. opAddAssign is called via +=, which can't be a valid symbol. The compiler absolutely has to forbid this, which might be tough to implement. - The meaning is a bit cryptic, kind of like opApply. I understand that it follows in line with other operators, so you might realize it is special, but it's not obvious that something is a property (this is really a bikeshed issue). + Because the function is of a different form than the property call, you can use it as a function easily. For example, easy to get a delegate to it, just &opSet_foo. + no changes to parser! No new keywords (some people value this, but I'm not really one of them) For a new keyword-style syntax (e.g. property int foo()): + Much easier for the compiler to resolve a conflict, since you are directly declaring the called symbol. + Easier to understand that foo is a property than with opSet_foo, and easier to know how to call it. - If you wanted to use the property as a function (for example, get a delegate to the property), it might be more difficult. For example, if a property is "property ref int foo()", &foo might give you the address of the returned value. I don't really know a great solution to this problem, maybe a cast? Maybe you forgo the ability to take the address of the return value, and just have it always be a delegate? - new keyword (some people might not like this, I don't really have a problem with it). + Easy to annotate groups of properties by enclosing them in an attribute block. ------ One more point. From my point of view, the readability of the code, and obvious meaning of the code to a user of the code is more important than the ease of development. I've always been a fan of verbose function names and variables which describe what the function/variable is rather than short easy to type names. For instance I loathe the module structure of phobos, simply because the module names are too terse. For me to try and find something, it's not obvious. So to that point, I think it's more important to make the readability and self-explanatory nature of properties better than to make them easier to declare. Remember, you only define them once, but you use them over and over. Where is it better to save time, on reading the docs or on writing the declaration? -SteveThe more I look at it, the more I like the keyword solution. I do find think you only absolutely need that if you are going to have context-keywords, which I DON'T think we need. I do find the whole With a keyword attribute, you could even group your properties together to save on typing/ugliness: property { int x() {} void x(int n) {} bool empty() {} }Not a fan, but this would work. I just don't see why I need to go through with it.
Jul 28 2009
Steven Schveighoffer wrote:On Mon, 27 Jul 2009 18:37:01 -0400, Andrei AlexandrescuOk, thanks.... with zero arguments.No, callable types period. Note that this does not compile: class A { int delegate(int foo) wyda() { return delegate int(int foo) { return foo;}; } } int main(string[] args) { auto a = new A; auto b = a.wyda(5); // line 14 auto c = a.wyda()(5); return 1; } [steves steveslaptop files]$ dmd testme.d testme.d(14): Error: function testme.A.wyda () does not match parameter types (int) testme.d(14): Error: expected 0 arguments, not 1 commenting out line 14 compiles.I think inferring meaning from the presence or absence of "()" is rather dicey.Knowing that you can call functions without parens, seeing code like: r.popFront; it's obvious that popFront is a function, not a property. But, do you agree that this code looks less-than-obvious? auto x = flush; is flush a flag saying flushing should occur? is it a function that flushes something, and returns the success? I agree that the bizarre factor is not as bad as with setters, but it's still not as self-explanatory as if you know that something without parens must be a property for the compiler to accept it.3. A getter can be defined in the opGet_X() form, and then using X() will be the eqivalent of opGet_X()(). There are small implications to leaving the existing getter syntax. Namely one can call a function not intended to be a getter in a property-like syntax, resulting in less-than-obvious code.This I don't agree with. I am very happy that I define popFront() as a method and then call it without parens.Let's separate this problem into two sections: 1. do we have to hint to the compiler that a function is a property or not? I think we do, otherwise, we have the strange setter anomalies, and the inability to return delegates from getters.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.) Andrei
Jul 28 2009
On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think inferring meaning from the presence or absence of "()" is rather dicey.Really? Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it. As one other person stated, they thought empty() emptied a range. Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names. The presence or absence of parens is a hard-coded accepted meaning of field vs. function. Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning). However, D does not allow intuitive names to be paired with the intuitive meaning of the presense or absence of parens, because you can't enforce it! Remember my example with TimeSpans? People will infer meaning from the presense or absense of parens whether you think it's a good idea or not. You will never get away from it.This is a band-aid fix, easily broken. int select(int timeoutMS = -1); // method on a socket, for example Hell, even my TimeSpan problem would still fail. Also you are forgoing the ability to have overloaded setters, which could be useful. Not to mention getters for delegates. -SteveLet's separate this problem into two sections: 1. do we have to hint to the compiler that a function is a property or not? I think we do, otherwise, we have the strange setter anomalies, and the inability to return delegates from getters.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)
Jul 28 2009
Steven Schveighoffer wrote:On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I didn't say not to infer meaning from the name.I think inferring meaning from the presence or absence of "()" is rather dicey.Really? Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it.As one other person stated, they thought empty() emptied a range.Well it doesn't.Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names.Sure.The presence or absence of parens is a hard-coded accepted meaning of field vs. function.I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning).allow you to write write-only properties, which do NOT behave at all like fields, and also read-only properties, which also don't behave like fields. Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.However, D does not allow intuitive names to be paired with the intuitive meaning of the presense or absence of parens, because you can't enforce it! Remember my example with TimeSpans? People will infer meaning from the presense or absense of parens whether you think it's a good idea or not. You will never get away from it.Well maybe you could change TimeSpan.This is a band-aid fix, easily broken. int select(int timeoutMS = -1); // method on a socket, for example Hell, even my TimeSpan problem would still fail.Let's separate this problem into two sections: 1. do we have to hint to the compiler that a function is a property or not? I think we do, otherwise, we have the strange setter anomalies, and the inability to return delegates from getters.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)Also you are forgoing the ability to have overloaded setters, which could be useful. Not to mention getters for delegates.Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good? Andrei
Jul 28 2009
On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:No, you're saying inferring meaning from parentheses is not a good idea. I think it's the same thing as saying that inferring the meaning from a function/field name is not a good idea (just in a more sarcastic way...). When you see parentheses, you infer function. When you don't you infer field/property. Note that I'm not just pulling this out of a hat, it's the way people already think, you should acknowledge that.On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I didn't say not to infer meaning from the name.I think inferring meaning from the presence or absence of "()" is rather dicey.Really? Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it.Exactly, so why do you think he thought that? Let's take someone who's used a language that uses () do denote a function, and no parens to denote a field (there are a few of them out there). Would that person ever think that x.empty; means "empty the contents of x"? The answer is no, not ever. Whether you like it or not or think it's dicey or not PEOPLE WILL INFER MEANING FROM PARENTHESES. I even do it, even though I *know* that it's dicey. I hate having to look up usages of things that make no sense because I have no idea what the code is doing. It's so much better when the meaning is clear from the code itself.As one other person stated, they thought empty() emptied a range.Well it doesn't.And for years, there have been complaints about it. This will continuously be a thorn in the side of D adoption until it is resolved.Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names.Sure.The presence or absence of parens is a hard-coded accepted meaning of field vs. function.I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.I'll give you that one, but that's an uncommon "because we can" case.Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning).allow you to write write-only properties, which do NOT behave at all like fieldsand also read-only properties, which also don't behave like fields.one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity. There's a subtle, yet very important difference. They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins with set is a better way to convey that contract via properties. D's implementation looks to me like a quick hack so D can say "look, we have properties!" They don't provide any of the interface benefits that true properties do. Might as well go back to Java style, where you have to name your properties getX, setX or isX. But now, normal functions are corrupted with the ability to use them as properties.Lovely. Force the developer to rename his functions because D is too weak to allow defining a correct interface. You didn't even address the select example, I think that's a very compelling example of something that breaks your rule. My point is that your rule only works if you write code in a certain way, and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec. It's like a prejudice against certain coding styles without any good reason.Well maybe you could change TimeSpan.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This is a band-aid fix, easily broken. int select(int timeoutMS = -1); // method on a socket, for example Hell, even my TimeSpan problem would still fail.Yes they do. It makes them behave like a variant field. e.g. x.timeout = 5.5; // set timeout to 5.5 seconds x.timeout = TimeSpan.seconds(5); // set timeout to 5 seconds exactly And what about getters for delegates? That problem is still unresolved by your rule. -SteveAlso you are forgoing the ability to have overloaded setters, which could be useful. Not to mention getters for delegates.Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?
Jul 28 2009
Steven Schveighoffer wrote:On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I acknowledge that in C, C++, and Java, you must add () to call an either a field access or execution of arbitrary code.Steven Schveighoffer wrote:No, you're saying inferring meaning from parentheses is not a good idea. I think it's the same thing as saying that inferring the meaning from a function/field name is not a good idea (just in a more sarcastic way...). When you see parentheses, you infer function. When you don't you infer field/property. Note that I'm not just pulling this out of a hat, it's the way people already think, you should acknowledge that.On Tue, 28 Jul 2009 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I didn't say not to infer meaning from the name.I think inferring meaning from the presence or absence of "()" is rather dicey.Really? Then why name your functions things like empty, why not ex245, to make them look it up, making *sure* they know what the meaning is before they use it.I acknowledge that some people infer meaning from parentheses. I mean, there's at least one :o).Exactly, so why do you think he thought that? Let's take someone who's used a language that uses () do denote a function, and no parens to denote a field (there are a few of them out there). Would that person ever think that x.empty; means "empty the contents of x"? The answer is no, not ever. Whether you like it or not or think it's dicey or not PEOPLE WILL INFER MEANING FROM PARENTHESES. I even do it, even though I *know* that it's dicey. I hate having to look up usages of things that make no sense because I have no idea what the code is doing. It's so much better when the meaning is clear from the code itself.As one other person stated, they thought empty() emptied a range.Well it doesn't.Again, most complaints have been directed towards writeln = 5. I think that's the major problem to be resolved.And for years, there have been complaints about it. This will continuously be a thorn in the side of D adoption until it is resolved.Being able to read code and understand what it means without resorting to documentation is the sign of a good choice of symbol names.Sure.The presence or absence of parens is a hard-coded accepted meaning of field vs. function.I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.I acknowledge that you give me that one.I'll give you that one, but that's an uncommon "because we can" case.Properties build on this notion by making a virtual field that actually resolves to a function (but behaves like a field, and this is an important accepted meaning).they allow you to write write-only properties, which do NOT behave at all like fieldslike an example to follow.and also read-only properties, which also don't behave like fields.one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention? That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.There's a subtle, yet very important difference. They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins provides a better way to convey that contract via properties.D's implementation looks to me like a quick hack so D can say "look, we have properties!" They don't provide any of the interface benefits that true properties do.What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.Might as well go back to Java style, where you have to name your properties getX, setX or isX. But now, normal functions are corrupted with the ability to use them as properties.Yum.Or maybe because her use of name was too ambiguous.Lovely. Force the developer to rename his functions because D is too weak to allow defining a correct interface.Well maybe you could change TimeSpan.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This is a band-aid fix, easily broken. int select(int timeoutMS = -1); // method on a socket, for example Hell, even my TimeSpan problem would still fail.You didn't even address the select example, I think that's a very compelling example of something that breaks your rule.I agree that that example reveals a problem. I also think that that problem could be solved, but I doubt that you'll be pleased.My point is that your rule only works if you write code in a certain way,Your rule also works if you write code in a certain way.and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec.opXxx are up to the spec.It's like a prejudice against certain coding styles without any good reason.I don't see that. I more see a prejudice against dropping "()" when calling a function.Then write a function that takes a variant instead of overloading.Yes they do. It makes them behave like a variant field.Also you are forgoing the ability to have overloaded setters, which could be useful. Not to mention getters for delegates.Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?e.g. x.timeout = 5.5; // set timeout to 5.5 seconds x.timeout = TimeSpan.seconds(5); // set timeout to 5 seconds exactly And what about getters for delegates? That problem is still unresolved by your rule.I believe it's a minor problem that does not impede people from getting work done. Andrei
Jul 28 2009
On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:Yes, I agree. But there is also a subtle problem we can solve at the same time. You keep missing the point. Let me come at another angle. You can't view properties as some sort of enforcement by the compiler. The compiler is not guaranteeing that if you call something without parentheses, it doesn't execute arbitrary code, it has nothing to do with what the compiler guarantees. But the *meaning* that the author of the function wishes to convey is available via the requirement of parentheses or lack thereof. The author of the code is saying "I wrote this function as if it were a field." It's the same thing as function names. The compiler allows you to name your functions how you wish, and enforces that foo is different than bar. Why is this important? Because foo does something different than bar. And to a user, that's obvious, because in english foo means something different than bar. What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name. For example: struct S { int foo(); int flu(); int bar(); } This is valid code: S s; s.fl(); s.b(); // s.f(); // doesn't compile because its not unambiguous Why is this advantageous? Well, it saves you from having to type the whole function name. It's unambiguous, so there is no problems as far as the compiler is concerned, so its easily implemented. But why don't we have a wonderful time-saving feature like this? Because it would be a nightmare to read. You can change the implied english meaning of the function by just using its prefix. But the compiler doesn't care, because it has no idea what the english meaning of the words are, and it's satisfied that you made an unambiguous decision. Back to our problem at hand, by allowing one to call functions with or without parentheses you are not only changing the implied meaning of the function, but you have removed the ability of the author to convey that meaning with simply the requirement of parentheses. He has to explain "this is a property" through by making the function name reflect that fact, or be an ass and say "well you shouldn't assume things based on parentheses, look it up dummy!" Yes, if we solve the problem of setters, we have killed a huge wart on D, but why ignore the other warts?And for years, there have been complaints about it. This will continuously be a thorn in the side of D adoption until it is resolved.Again, most complaints have been directed towards writeln = 5. I think that's the major problem to be resolved.Just like D! struct S { const int readonlyfield; int readonlyproperty(); } Yes, that's right. readonly is analogous to const.like an example to follow.and also read-only properties, which also don't behave like fields.that's one of the benefits of properties, you can do things that you can't do with fields, otherwise why have them?I explained this above. I'll reiterate: The enforcement of "field-like" by the compiler is not the point of properties, the ability given to the author to document that fact is the point.Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention? That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.It's less verbose, makes the code read better, allows you to avoid using functions to do everything. As another example, Java doesn't have operator overloading, so BigInteger is horrific to use, calling functions overloading isn't better because operators are just functions, why call them something else?There's a subtle, yet very important difference. They saw the implementation of properties in Java as a good thing, but Java relied on a social standard that a method that begins with get is a getter, a method that begins with set is a setter, and a method that begins with properties.No. The interface benefits are explained above.D's implementation looks to me like a quick hack so D can say "look, we have properties!" They don't provide any of the interface benefits that true properties do.What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.I want to use the parentheses or lack thereof as part of the human meaning for the function/property. Making them optional means I can't do that.Or maybe because her use of name was too ambiguous.Well maybe you could change TimeSpan.Lovely. Force the developer to rename his functions because D is too weak to allow defining a correct interface.I would be pleased, how can it be solved?You didn't even address the select example, I think that's a very compelling example of something that breaks your rule.I agree that that example reveals a problem. I also think that that problem could be solved, but I doubt that you'll be pleased.But my way is orthogonal to writing normal functions. Your rule mistakenly identifies normal functions as properties.My point is that your rule only works if you write code in a certain way,Your rule also works if you write code in a certain way.Yes, and it is well established that opXxx shouldn't be used for arbitrary function names. But you are expanding that rule to basically any function name, which means all functions are subject to being misinterpreted by the compiler, no matter what you name them.and I don't think that should be a determination of whether something is a property or not by the compiler, because the naming of functions is supposed to be up to the developer, not the spec.opXxx are up to the spec.It's a sacrifice in the name of clarity.It's like a prejudice against certain coding styles without any good reason.I don't see that. I more see a prejudice against dropping "()" when calling a function.I can live without overloading setters, I don't think it's a requirement, but it would be possible with my method. That's the only point I was trying to make. -SteveThen write a function that takes a variant instead of overloading.Yes they do. It makes them behave like a variant field.Also you are forgoing the ability to have overloaded setters, which could be useful. Not to mention getters for delegates.Wait, overloaded setters do NOT make the thing behave like a field, but you were stating how nice that is a few paragraphs ago! So what is it that you think is good?
Jul 28 2009
On Tue, Jul 28, 2009 at 10:20 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name why don't we have a wonderful time-saving feature like this? =A0Because it would be a nightma=re toread.......like an example to follow.Just like D! Yes, that's right. =A0readonly is analogous to const.? Bravo! Fine, rational arguments, Steve.That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!... better because operators are just functions, why call them something else=tooWell maybe you could change TimeSpan.=A0Lovely. =A0Force the developer to rename his functions because D is =gI want to use the parentheses or lack thereof as part of the human meanin=weak to allow defining a correct interface.Or maybe because her use of name was too ambiguous.for the function/property. =A0Making them optional means I can't do that.I think Andrei's right here. .seconds() really was too ambiguous a name to begin with. Even if we had properties I would be inclined to think that was just something you forgot to mark as a property because a property-like meaning is all that makes sense to me. The meaning of .fromSeconds() is much more obvious. The example of adjectives or nouns that are also verbs is much better --- .empty vs .empty(). Others that come to mind: clean, dirty, end, begin. (begin isn't really a noun but it's been used that way for so long in STL that C++ people think of it as a synonym for "beginning".) --bb
Jul 28 2009
On Tue, 28 Jul 2009 13:51:11 -0400, Bill Baxter <wbaxter gmail.com> wrote:On Tue, Jul 28, 2009 at 10:20 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:I think in the sense that 'seconds' is not a verb, and therefore, it's not obvious (perhaps to some) that TimeSpan.seconds(5); returns a TimeSpan that represents 5 seconds is a valid point. But what happens in those cases is the user is slightly confused and looks up the docs (probably once). The argument from Andrei is simply dodging the issue. ts.seconds = 5; Means the same thing (even with Andrei's new rule), and not because I poorly named the function, but because I happened to name it the same as a member function. That you can call a static function via an instance is one bug IMO, and the other is that the function is even considered as a property.I want to use the parentheses or lack thereof as part of the human meaning for the function/property. Making them optional means I can't do that.I think Andrei's right here. .seconds() really was too ambiguous a name to begin with. Even if we had properties I would be inclined to think that was just something you forgot to mark as a property because a property-like meaning is all that makes sense to me. The meaning of .fromSeconds() is much more obvious.The example of adjectives or nouns that are also verbs is much better --- .empty vs .empty(). Others that come to mind: clean, dirty, end, begin. (begin isn't really a noun but it's been used that way for so long in STL that C++ people think of it as a synonym for "beginning".)I was using a real-life example, I think that has some power to it. But you are right, naming the static method differently was probably the right move anyways, and there are better theoretical examples. There was some pressure to make the usage less verbose... -Steve
Jul 28 2009
Bill Baxter wrote:On Tue, Jul 28, 2009 at 10:20 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:I don't think it's a good argument. Operators are functions with a specific syntax, is all. D is not even pretending any different: it simply rewrites the usual syntax into function calls. We should do the same with properties. AndreiOn Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name why don't we have a wonderful time-saving feature like this? Because it would be a nightmare to read.......like an example to follow.Just like D! Yes, that's right. readonly is analogous to const.Bravo! Fine, rational arguments, Steve.That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!... better because operators are just functions, why call them something else?
Jul 28 2009
On Tue, 28 Jul 2009 14:19:49 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:I was using this as an example of how your arguments against property definitions sound to me. Operators are not the same as properties -- the definition syntax is the same word, every time. So once you learn that the non-english term opAdd defines what happens when you type +, you can repeatedly use that knowledge. For example, I know that for the following code: x + y; I know this means "add x to y," and it might call opAdd or it might be a builtin operation, I don't care, but I know it means to add. It might even execute arbitrary code that does something completely different, but it's not my fault because the author didn't follow the standard convention. I don't have to look it up, or know what the author of object x meant, the meaning is not subject to debate or English ambiguity. However, when I see: x.empty; I can't tell what is implied here. empty could be a field or property, in which case the user made a logic error, or it could be a function that empties x, or it could be some code that does something completely different. I assume the author is going to name his functions after what they do, similarly to how opAdd should be used for addition. English is not precise, and can have multiple meanings for the same exact word. Context is important. But it gets worse. Now I see this: y.empty; Oh, I learned what empty meant before, right? WRONG! y could be written by a completely different author, and could have the opposite meaning. The problem is, you can't come up with a non-prejudiced definition of what empty should always mean, because the English term itself is ambiguous. All you can do is use conventions that can be defined, such as () performs an action, but lack of () denotes a field, or come up with java-like conventions (e.g. doXxx means it's a function). So if I can couple the term empty with the context of lack of parentheses meaning field, I can deduce the meaning of empty *without looking it up*. The advantage is not having to look up what code means because the author did a good job of naming the function/property. This is currently impossible with D. Coming up with bizarre rules that require pairs of functions doesn't make things any easier. I still have to look up the usage of empty every time I encounter a new usage of it, because it could mean one of two things. -SteveOn Tue, Jul 28, 2009 at 10:20 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:I don't think it's a good argument. Operators are functions with a specific syntax, is all. D is not even pretending any different: it simply rewrites the usual syntax into function calls. We should do the same with properties.On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name why don't we have a wonderful time-saving feature like this? Because it would be a nightmare to read.......look like an example to follow.Just like D! Yes, that's right. readonly is analogous to const.Bravo! Fine, rational arguments, Steve.That's what I'm saying: if it could do anything, at least don't pretend it's anything special. It's a function!... better because operators are just functions, why call them something else?
Jul 28 2009
Steven Schveighoffer wrote:However, when I see: x.empty; I can't tell what is implied here.you better know what it's supposed to do. D simply doesn't make it "bad Andrei
Jul 28 2009
On Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them. -SteveHowever, when I see: x.empty; I can't tell what is implied here.you better know what it's supposed to do. D simply doesn't make it "bad
Jul 28 2009
Steven Schveighoffer wrote:On Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already. Then you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved. But your arguments are not convincing to me, and in turn I explained why. What would you do if you were me? AndreiSteven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't make
Jul 28 2009
Andrei Alexandrescu pisze:Steven Schveighoffer wrote:You should just accept what others want *although* you don't agree... Steve's arguments are very good and convincing, and unfortunately somehow you don't get them. And I don't see your arguments being superior at all. Sorry for thread hijacking, but such discussions make me want not to use D any more... I am writing because I still have some hope... Maybe community should decide in poll who's arguments are better? BR Marcin KuszczakOn Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already. Then you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved. But your arguments are not convincing to me, and in turn I explained why. What would you do if you were me? AndreiSteven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't make
Jul 28 2009
aarti_pl wrote:Andrei Alexandrescu pisze:I'd like to see a poll about this. I think just a few want the ability to remove the () from an argument-less function call, and all of us others want the opposite.Steven Schveighoffer wrote:You should just accept what others want *although* you don't agree... Steve's arguments are very good and convincing, and unfortunately somehow you don't get them. And I don't see your arguments being superior at all. Sorry for thread hijacking, but such discussions make me want not to use D any more... I am writing because I still have some hope... Maybe community should decide in poll who's arguments are better?On Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already. Then you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved. But your arguments are not convincing to me, and in turn I explained why. What would you do if you were me? AndreiSteven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't make
Jul 28 2009
aarti_pl wrote:Andrei Alexandrescu pisze:I do get his arguments. Not being convinced does not mean I don't understand them. You seem to assume that as soon as I understood his arguments I'd automatically agree, so somehow I don't understand them.Steven Schveighoffer wrote:You should just accept what others want *although* you don't agree... Steve's arguments are very good and convincing, and unfortunately somehow you don't get them. And I don't see your arguments being superior at all.On Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already. Then you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved. But your arguments are not convincing to me, and in turn I explained why. What would you do if you were me? AndreiSteven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't makeSorry for thread hijacking, but such discussions make me want not to use D any more... I am writing because I still have some hope...D has great features, and probably less warts than most other languages. I understand how you feel, but I'd also hope that realistically your use of the language hinges on a little more than this one issue.Maybe community should decide in poll who's arguments are better?That would be helpful. Andrei
Jul 28 2009
Andrei Alexandrescu:Designing a language with polls is an obvious idea, but I have not suggested it in the past because it has some drawbacks too (there's a risk of losing the coherence of the language and to use "political" solutions that are mostly good to close the muzzle of the majority of people). On the other hand it has some advantages too (example: despite you are intelligent, some names and function/templates signatures you have added to Phobos may be not good because you aren't equal to the average person, everyone has some personal quirks. So designing by poll helps remove such quirks). So this time, as an experiment, we may try to see what happens using a poll :-) Language design polls must be not anonymous, each vote must have a name beside it. I think that a poll done in the past may have lead to different outcomes (for example in two recent changes to the "switch", one by you and one by Walter). Bye, bearophileMaybe community should decide in poll who's arguments are better?That would be helpful.
Jul 28 2009
bearophile wrote:Andrei Alexandrescu:Great thoughts. One thing that maybe is not clear is that I afford to argue in these debates exactly because I don't get to decide. Walter never implements something that is not convinced of. It happens often that I suggest an improvement that he doesn't approve for one reason or another. Last time I suggested that switch should work with all types that support comparison (it's just weird that it only works with ints and strings), but he refused to consider it at least for the time being. So, polls would be very useful to gauge what people want. That's very solid information. AndreiDesigning a language with polls is an obvious idea, but I have not suggested it in the past because it has some drawbacks too (there's a risk of losing the coherence of the language and to use "political" solutions that are mostly good to close the muzzle of the majority of people). On the other hand it has some advantages too (example: despite you are intelligent, some names and function/templates signatures you have added to Phobos may be not good because you aren't equal to the average person, everyone has some personal quirks. So designing by poll helps remove such quirks). So this time, as an experiment, we may try to see what happens using a poll :-) Language design polls must be not anonymous, each vote must have a name beside it. I think that a poll done in the past may have lead to different outcomes (for example in two recent changes to the "switch", one by you and one by Walter).Maybe community should decide in poll who's arguments are better?That would be helpful.
Jul 28 2009
Andrei Alexandrescu:So, polls would be very useful to gauge what people want. That's very solid information.I want to add two small things: 1) Votes must follow a period of discussions, and possibly even a summary that lists the most common ideas. Otherwise lot of people will base their vote on an insufficient level of knowledge of the topic :-) 2) Votes (or proposals) may be all equal, with always a "weight" of 1. OR they may have a variable weight, that for example comes from the estimated experience (or importance) of a person on a topic. For example once I have seen Guido V. Rossum vote for something with with a weight of 1000 (it essentially meant that his decision was the final one). It means that for example I can accept that a vote by Bartoz regarding some concurrency topic is much more heavy (important) than mine, because I know very little about that topic compared to him. In practice to keep things practical most people have a weight of 1, with few known exceptions (for example if you define the API of regex you may have a weight of 4 or 5). Bye, bearophile
Jul 28 2009
bearophile escribi:Andrei Alexandrescu:Do you know such a poll system that's free? I just created a poll, but forgot about these points...So, polls would be very useful to gauge what people want. That's very solid information.I want to add two small things: 1) Votes must follow a period of discussions, and possibly even a summary that lists the most common ideas. Otherwise lot of people will base their vote on an insufficient level of knowledge of the topic :-) 2) Votes (or proposals) may be all equal, with always a "weight" of 1. OR they may have a variable weight, that for example comes from the estimated experience (or importance) of a person on a topic. For example once I have seen Guido V. Rossum vote for something with with a weight of 1000 (it essentially meant that his decision was the final one). It means that for example I can accept that a vote by Bartoz regarding some concurrency topic is much more heavy (important) than mine, because I know very little about that topic compared to him. In practice to keep things practical most people have a weight of 1, with few known exceptions (for example if you define the API of regex you may have a weight of 4 or 5).
Jul 28 2009
bearophile:(for example if you define the API of regex you may have a weight of 4 or 5).<Just to be sure of what I mean: it mans you can express a vote in the closed interval [-5 .. +5], you aren't forced to vote just -5 and +5 :-) Bye, bearophile
Jul 28 2009
On Tue, Jul 28, 2009 at 1:49 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:aarti_pl wrote:I think the expectation is more that you would address or respond to his argument rather than making your own argument again. Or say something like this: The fundamental difference in our viewpoints is that you believe that expressing extra semantic information to people who read the code is more valuable that saving some typing. I believe the opposite. (feel free to rewrite as you wish) Then it is clear that you have understood his argument and have some idea how and where the difference in opinion really comes from. Simply repeating your argument makes it look as though you have not read his.I do get his arguments. Not being convinced does not mean I don't understand them. You seem to assume that as soon as I understood his arguments I'd automatically agree, so somehow I don't understand themWhat would you do if you were me? AndreiYou should just accept what others want *although* you don't agree... Steve's arguments are very good and convincing, and unfortunately somehow you don't get them. And I don't see your arguments being superior at all.I don't think it's this one issue he's talking about. I think the issue is an occasionally repeated history of questionable changes in D made in the face of strong community opposition. Like foreach_reverse. Such choices may be perfectly valid, but if you find yourself repeatedly not seeing eye-to-eye with the designers of a language, you have to wonder if you're in the right language community. --bbSorry for thread hijacking, but such discussions make me want not to use D any more... I am writing because I still have some hope...D has great features, and probably less warts than most other languages. I understand how you feel, but I'd also hope that realistically your use of the language hinges on a little more than this one issue.
Jul 28 2009
Bill Baxter wrote:On Tue, Jul 28, 2009 at 1:49 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Well we both repeated our arguments several times :o). And don't forget: I don't get to decide. So such a discussion between Steve and me could as well be a discussion between any two participants. I do have accountability for Phobos, and there haven't been huge debates about it that I vetoed against, have there?aarti_pl wrote:I think the expectation is more that you would address or respond to his argument rather than making your own argument again. Or say something like this: The fundamental difference in our viewpoints is that you believe that expressing extra semantic information to people who read the code is more valuable that saving some typing. I believe the opposite. (feel free to rewrite as you wish) Then it is clear that you have understood his argument and have some idea how and where the difference in opinion really comes from. Simply repeating your argument makes it look as though you have not read his.I do get his arguments. Not being convinced does not mean I don't understand them. You seem to assume that as soon as I understood his arguments I'd automatically agree, so somehow I don't understand themWhat would you do if you were me? AndreiYou should just accept what others want *although* you don't agree... Steve's arguments are very good and convincing, and unfortunately somehow you don't get them. And I don't see your arguments being superior at all.I understand. On the other hand, a lot of good things have been done in relative silence, which are likely to positively impact code writing experience a great deal. They just need some more riping. For example, I consider the recently-introduced value range propagation an excellent feature and a well-balanced engineering tradeoff. Such a thing *would* be the kind of feature that would make me cast an interested eye over a language. Finally, a step forward in the always-muddy world of fixed-size integer arithmetic. Then probably I'd try value range propagation and see the compiler essentially fail for all cases (Walter, Walter... I wonder if you had *any* test case for the thing) and then give up in frustration. AndreiI don't think it's this one issue he's talking about. I think the issue is an occasionally repeated history of questionable changes in D made in the face of strong community opposition. Like foreach_reverse. Such choices may be perfectly valid, but if you find yourself repeatedly not seeing eye-to-eye with the designers of a language, you have to wonder if you're in the right language community.Sorry for thread hijacking, but such discussions make me want not to use D any more... I am writing because I still have some hope...D has great features, and probably less warts than most other languages. I understand how you feel, but I'd also hope that realistically your use of the language hinges on a little more than this one issue.
Jul 28 2009
On Tue, Jul 28, 2009 at 2:35 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:IOn Tue, Jul 28, 2009 at 1:49 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Well we both repeated our arguments several times :o). And don't forget: =I think the expectation is more that you would address or respond to his argument rather than making your own argument again. Or say something like this: The fundamental difference in our viewpoints is that you believe that expressing extra semantic information to people who read the code is more valuable that saving some typing. =A0I believe the opposite. (feel free to rewrite as you wish) =A0Then it is clear that you have understood his argument and have some idea how and where the difference in opinion really comes from. =A0 Simply repeating your argument makes it look as though you have not read his.don't get to decide. So such a discussion between Steve and me could as w=ellbe a discussion between any two participants.That's not quite true. You do talk to Walter more than Steve does. And I think everyone can guess that if you don't get convinced there's no way Walter will be. Convincing you isn't sufficient, but it is necessary.I do have accountability for Phobos, and there haven't been huge debates about it that I vetoed against, have there?You have indeed made a good effort there. It was iffy for a while with the head/toe thing, but you did come around. :-)fI don't think it's this one issue he's talking about. =A0I think the issue is an occasionally repeated history of questionable changes in D made in the face of strong community opposition. =A0Like foreach_reverse. =A0Such choices may be perfectly valid, but if you find yourself repeatedly not seeing eye-to-eye with the designers of a language, you have to wonder if you're in the right language community.I understand. On the other hand, a lot of good things have been done in relative silence, which are likely to positively impact code writing experience a great deal. They just need some more riping. For example, I consider the recently-introduced value range propagation an excellent feature and a well-balanced engineering tradeoff. Such a thing *would* be the kind of feature that would make me cast an interested eye over a language. Finally, a step forward in the always-muddy world of fixed-size integer arithmetic. Then probably I'd try value range propagation and see the compiler essentially fail for all cases (Walter, Walter... I wonder i=you had *any* test case for the thing) and then give up in frustration.There's probably a connection there with human nature's way of remembering affronts much more clearly and dearly than compliments. --bb
Jul 28 2009
Bill Baxter wrote:On Tue, Jul 28, 2009 at 2:35 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Oh yeah? How about "lazy"? AndreiBill Baxter wrote:That's not quite true. You do talk to Walter more than Steve does. And I think everyone can guess that if you don't get convinced there's no way Walter will be. Convincing you isn't sufficient, but it is necessary.On Tue, Jul 28, 2009 at 1:49 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: I think the expectation is more that you would address or respond to his argument rather than making your own argument again. Or say something like this: The fundamental difference in our viewpoints is that you believe that expressing extra semantic information to people who read the code is more valuable that saving some typing. I believe the opposite. (feel free to rewrite as you wish) Then it is clear that you have understood his argument and have some idea how and where the difference in opinion really comes from. Simply repeating your argument makes it look as though you have not read his.Well we both repeated our arguments several times :o). And don't forget: I don't get to decide. So such a discussion between Steve and me could as well be a discussion between any two participants.
Jul 28 2009
On Tue, Jul 28, 2009 at 4:45 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:: IOn Tue, Jul 28, 2009 at 2:35 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:On Tue, Jul 28, 2009 at 1:49 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote: I think the expectation is more that you would address or respond to his argument rather than making your own argument again. Or say something like this: The fundamental difference in our viewpoints is that you believe that expressing extra semantic information to people who read the code is more valuable that saving some typing. =A0I believe the opposite. (feel free to rewrite as you wish) =A0Then it is clear that you have understood his argument and have some idea how and where the difference in opinion really comes from. =A0 Simply repeating your argument makes it look as though you have not read his.Well we both repeated our arguments several times :o). And don't forget=welldon't get to decide. So such a discussion between Steve and me could as=I mean in this case, since Walter seems happy to leave things as-is. His expressed desire is to change things as little as possible here. So if you say a new keyword isn't necessary the chance of a new keyword is basically zero. --bbOh yeah? How about "lazy"?be a discussion between any two participants.That's not quite true. =A0You do talk to Walter more than Steve does. And I think everyone can guess that if you don't get convinced there's no way Walter will be. =A0Convincing you isn't sufficient, but it is necessary.
Jul 28 2009
On Tue, 28 Jul 2009 16:21:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:No, b has no meaning. It's not an English word. a.filter() looks like it should filter something. a.filter looks like it should access a filter. But in D, a.filter could mean either, which I guess is fine if you want to return a filter, and a.filter() should perform a filtering action. If it doesn't, the author wrote his code incorrectly. It's as simple as that.On Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already.Steven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't makeThen you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved.-Steve
Jul 28 2009
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:I totally agree with Steven's arguments (and have enjoyed reading the discussion). I think the reason he says you're "not getting it" is because your examples tend to be "a.b" whereas his examples tend to be "a.empty". In your examples, you've stripped away the distinct function/field names and presented the argument from the compiler's perspective: in terms of arbitrary symbols that might either perform a pointer dereference or a function invocation. Steve's arguments, on the other hand, are all from the perspective of the programmer. The parentheses following the identifier act as *punctuation* that clarify intent. Good? Good. --benjiOn Tue, 28 Jul 2009 16:08:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I do read them and understand them. I mean, it's not rocket surgery. At the end of the day you say "x = a.b;" looks more like sheer access because that's what happens for fields already. Then you say "a.b()" in any context looks more like an action because it's clear that there's a function call involved. But your arguments are not convincing to me, and in turn I explained why. What would you do if you were me? AndreiSteven Schveighoffer wrote:still not getting it, are you... Just forget it, I think this is a lost cause, I keep making the same points over and over again, and you keep not reading them.However, when I see: x.empty; I can't tell what is implied here.that you better know what it's supposed to do. D simply doesn't make
Jul 30 2009
On Tue, Jul 28, 2009 at 11:19 AM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:mareOn Tue, Jul 28, 2009 at 10:20 AM, Steven Schveighoffer<schveiguy yahoo.com> wrote:On Tue, 28 Jul 2009 12:30:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:What if the compiler allowed you to call functions as long as what you typed was an unambiguous prefix of the function name why don't we have a wonderful time-saving feature like this? =A0Because it would be a night=okto read....d...like an example to follow.Just like D! Yes, that's right. =A0readonly is analogous to const.That's what I'm saying: if it could do anything, at least don't preten=icI don't think it's a good argument. Operators are functions with a specif=Bravo! =A0Fine, rational arguments, Steve.it's anything special. It's a function!... better because operators are just functions, why call them something else?syntax, is all. D is not even pretending any different: it simply rewrite=sthe usual syntax into function calls. We should do the same with properti=es. I think I basically agree with you on that except: 1) The function call syntax should be disabled on properties to avoid ambiguities like returned delegates or things with opCall. 2) the function name that properties are rewritten into should be hidden from the programmer. With opAdd etc, the function you are trying to write corresponds to a symbol, so you can't have it be your identifier. So goofy names like opAdd are necessary and unavoidable. With properties, the thing in question has a name, so it is more pleasing to actually use it. But certainly, property accesses will still be rewritten as functions. It could even be opGet_foo internally. But who wants to look at a dozen functions with names like opGet_ opSet_? Yes, my main argument against opGet_ is that it is butt-ugly. The problem is that most every class has multiple properties. So every class will have to sprout this ugliness. But sprouting a few property {...} blocks or even "property:" sections is not so bad. In fact I seen no reason why you couldn't just make the rule be that we rewrite the properties both at point of use *and* at point of declaration. property int foo() { return x_; } would be rewritten int opGet_foo() { return x_; } And I suppose I don't see any reason to stop anyone from writing the latter if they somehow find it more aesthetically pleasing. Or find it more useful for code generation or something. --bb
Jul 28 2009
Tue, 28 Jul 2009 13:20:30 -0400, Steven Schveighoffer wrote:Let me come at another angle. You can't view properties as some sort of enforcement by the compiler. The compiler is not guaranteeing that if you call something without parentheses, it doesn't execute arbitrary code, it has nothing to do with what the compiler guarantees. But the *meaning* that the author of the function wishes to convey is available via the requirement of parentheses or lack thereof. The author of the code is saying "I wrote this function as if it were a field."I think the reason is purely syntactical. Specifically to distinguish nouns from verbs. Many English words can be used as both. "Empty" may mean "contains nothing" or "to throw everything away" and both meanings are equally valid. You need context to derive the correct meaning of a word. You always have such context in human language because of its nature. Programming languages are much more formalized which robs you of context. Parentheses make a perfect syntactic convention for anybody familiar with C family languages: verbs have parens, nouns (adjectives, adverbs) don't. Because functions do things but variables do not. So when I complexity. I simply state: "This *word* is not a verb. Read it accordingly." And it's immediately clear to me that "empty" is "nothing inside" while "empty()" is "do cleanup".
Jul 28 2009
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:Back to semantics by convention? Whenever you write *anything*, there's always semantic by convention. writefln("Foo"); That writefln could just do antyhing with it's argument, maybe return it twice. So how do you enforce writefln to actually write something? Aaaah... D sucks because it can't enforce that.On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.
Jul 28 2009
Ary Borenszweig wrote:Andrei Alexandrescu wrote:I was replying to the expectation that a.foo() does an action and a.foo allegedly does not. AndreiSteven Schveighoffer wrote:Back to semantics by convention? Whenever you write *anything*, there's always semantic by convention. writefln("Foo"); That writefln could just do antyhing with it's argument, maybe return it twice. So how do you enforce writefln to actually write something? Aaaah... D sucks because it can't enforce that.On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Which is not, because it can execute arbitrary code that is not restricted in any way. How good a design is that? Back to semantics by convention?Guess what - they both behave like functions. So their properties are an elaborate mechanism that is actually thoroughly unchecked, thus going back to what you could do by calling functions. So why the hell did they define the feature in the first place? Oh, for allowing people to write a.foo() instead of a.foo. You know what, that's a bit disappointing for an entire language feature.No, they did it to *force* you to write a.foo instead of a.foo(), to make it more defined that foo is a field-like entity.
Jul 28 2009
I C++, I write a lot of functions with names in the form of get_foo, set_foo, or is_foo. The get/set/is isn't just clutter, it serves an important function in describing the semantics of the function. A function named 'empty' has different semantics than a function named 'is_empty'. A function named 'get_color' has different semantics than a function named 'color'. To me, 'y = x;' makes a lot of sense as syntax sugar for 'y = get_x();', but makes no sense as syntax sugar for 'y = x();'. Writing 'y = get_x;' instead of 'y = get_x();' is barely an improvement, and nowhere near as nice as 'y = x;'. Likewise, 'x = y;' makes sense as syntax sugar for 'set_x(y);', but not as syntax sugar for 'x(y);'. I don't want to have to write 'set_x = y;'. So, yes, properties are just functions. However, they are /different/ functions from the functions with the same name as the property, with different semantics. Its use as a property is logically part of the name of a function. -- Rainer Deyke - rainerd eldwood.com
Jul 28 2009
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:Just because it could do anything doesn't mean it *has* to do anything. Again, D ranges suck because the compiler can't enforce you that empty, pop, etc., actually do what their name says.On Tue, 28 Jul 2009 11:11:09 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: D's implementation looks to me like a quick hack so D can say "look, we have properties!" They don't provide any of the interface benefits that true properties do.What are the interface benefits that "true" properties do? What is a "true" property? Something that could do anything. Surprise, that was already the charter of functions. Well thank you very much.
Jul 28 2009
Tue, 28 Jul 2009 11:30:00 -0500, Andrei Alexandrescu wrote:I think it is mentioned more often because you tend to agree with it. There are many more as valid arguments which you discard or ignore, mainly maintainability.Again, most complaints have been directed towards writeln = 5. I think that's the major problem to be resolved.And for years, there have been complaints about it. This will continuously be a thorn in the side of D adoption until it is resolved.The presence or absence of parens is a hard-coded accepted meaning of field vs. function.I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.
Jul 28 2009
Andrei Alexandrescu wrote:Steven Schveighoffer wrote:The presence or absence of parens is a hard-coded accepted meaning of ==20field vs. function.=20 I understand how some people want to derive meaning from obj.foo()=20 versus obj.foo. I think they shouldn't in D. I mean D has had for years=the behavior that you could drop the trailing empty parentheses. =20<sarcasm> And of course, D has such a huge number of users already that=20 anyone who comes from another language can just go to hell as far as=20 we're concerned... </sarcasm> Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jul 28 2009
Jérôme M. Berger wrote:Andrei Alexandrescu wrote:But then they'd expect a number of improvements wouldn't they. To me, the space-wasting and uncomfortable-to-type parens have always been unpleasant noise. I like some of the values of the old village I grew up in, but please pave the darn road, I could do without the mud. AndreiSteven Schveighoffer wrote:<sarcasm> And of course, D has such a huge number of users already that anyone who comes from another language can just go to hell as far as we're concerned... </sarcasm>The presence or absence of parens is a hard-coded accepted meaning of field vs. function.I understand how some people want to derive meaning from obj.foo() versus obj.foo. I think they shouldn't in D. I mean D has had for years the behavior that you could drop the trailing empty parentheses.
Jul 28 2009
On Tue, Jul 28, 2009 at 03:07:34PM -0500, Andrei Alexandrescu wrote:To me, the space-wasting and uncomfortable-to-type parens have always been unpleasant noise.For what it's worth, I agree with this. -- Adam D. Ruppe http://arsdnet.net
Jul 28 2009
On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments. For instance: protected void foo(Object o); public pure const const(Object) foo(); Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar". -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 28 2009
Michel Fortin wrote:On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike. AndreiWell I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments. For instance: protected void foo(Object o); public pure const const(Object) foo(); Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".
Jul 28 2009
On 2009-07-28 11:37:05 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Michel Fortin wrote:Also, what if a derived class implements a getter while the base class only has a setter. Does that mean that only the derived class can use the property syntax on the base class' setter? What I don't like about that proposal is that that how to call a setter is bound to the existence of another function in the same scope using pretty non-obvious rules. Also, it doesn't solve the problem of the getter that returns a delegate since you can continue using the function notation with properties and you can continue to call functions with no parenthesis. While I like too being able to call functions with no argument by skipping the tailing parenthesis, I'd easily give up on that if it means I can get a language with less ambiguities. I also happen to agree with Walter and you that it wouldn't be so great to just decorate functions with a keyword to give them a different syntax. I've propsed earlier a namespace-like syntax where you can have functions like "foo.opAssign" inside a class (or anywhere really) that you can call with "foo = x", unifying properties with operator overloading. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments. For instance: protected void foo(Object o); public pure const const(Object) foo(); Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".
Jul 28 2009
Michel Fortin wrote:On 2009-07-28 11:37:05 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:It all follows normal language rules. That's what I like about rewrites (lowerings): they allow you to reason about a new mini-feature (that in this case is absolutely nothing beyond a minor syntactic convenience) in terms of the rest of the language.Michel Fortin wrote:Also, what if a derived class implements a getter while the base class only has a setter. Does that mean that only the derived class can use the property syntax on the base class' setter?On 2009-07-28 10:16:16 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Well I chose the rule that makes bar look and feel as much as an assignable value as possible. The rule could be relaxed (e.g. by dropping qualifiers), but that means we're departing from assignable value lookalike.Well I don't think so. To repeat what I wrote elsethread: foo = bar is rewritten into foo(bar) if and only if auto __x = foo, __x = bar works. This means, a setter only works if there's a corresponding getter. (Write-only properties be damned.)This may lead to strange issues if both the setter and the getter don't have the same protection attribute, or purity, or constness of arguments. For instance: protected void foo(Object o); public pure const const(Object) foo(); Here, you can assign to foo using the property syntax only from a non-pure functions of this class or a derived classes and when the value you're assinging is a const(Object). Elsewhere, you can only assign using the function syntax. Anything else would break "auto __x = foo, __x = bar".What I don't like about that proposal is that that how to call a setter is bound to the existence of another function in the same scope using pretty non-obvious rules.I think the rules are very obvious.Also, it doesn't solve the problem of the getter that returns a delegate since you can continue using the function notation with properties and you can continue to call functions with no parenthesis.It doesn't solve the problem with a getter that returns a delegate. People who want to return delegates must use an extra pair of parens.While I like too being able to call functions with no argument by skipping the tailing parenthesis, I'd easily give up on that if it means I can get a language with less ambiguities.I wouldn't want to hurt the majority of my code for an obscure case. I do agree I'd rather not have an obscure case in the first place.I also happen to agree with Walter and you that it wouldn't be so great to just decorate functions with a keyword to give them a different syntax. I've propsed earlier a namespace-like syntax where you can have functions like "foo.opAssign" inside a class (or anywhere really) that you can call with "foo = x", unifying properties with operator overloading.That would work. Many things would work. Andrei
Jul 28 2009
Ary Borenszweig wrote:Maybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like: int property foo(); // getter int property foo(int value); // setterMy proposal requires no new keywords and no new syntax: int getfoo(); // getter int setfoo(int); // setter -- Rainer Deyke - rainerd eldwood.com
Jul 24 2009
Rainer Deyke wrote:Ary Borenszweig wrote:This is pretty clean, and in keep with the opXxx approach. Actually how about defining property foo by defining opGet_foo and opSet_foo. AndreiMaybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like: int property foo(); // getter int property foo(int value); // setterMy proposal requires no new keywords and no new syntax: int getfoo(); // getter int setfoo(int); // setter
Jul 24 2009
On 2009-07-24 22:58:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:This is pretty clean, and in keep with the opXxx approach. Actually how about defining property foo by defining opGet_foo and opSet_foo.The problem with this is that it's ugly. What about this int foo.opGet(); // getter void foo.opAssign(int); // setter with some support from the compiler. It could even be exteded to support more: int foo.opIndex(int); // foo[1]; void foo.opAddAssign(int); / foo += 1; void foo.invert(); // special function attached to property -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 24 2009
Michel Fortin wrote:On 2009-07-24 22:58:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:There is a thread discussing the proposal which is also linked to by the wiki. Posting there would be useful, for future reference too.This is pretty clean, and in keep with the opXxx approach. Actually how about defining property foo by defining opGet_foo and opSet_foo.The problem with this is that it's ugly. What about this int foo.opGet(); // getter void foo.opAssign(int); // setter with some support from the compiler. It could even be exteded to support more: int foo.opIndex(int); // foo[1]; void foo.opAddAssign(int); / foo += 1; void foo.invert(); // special function attached to property
Jul 24 2009
Andrei Alexandrescu wrote:Rainer Deyke wrote:Actually, if this became the "official" way of doing properties, that would solve the IDE and debugger issues and (hopefully) the parens thing. Which leaves only one issue: that writing properties violates DRY. So I wrote a basic Property generator. Full source is here: http://gist.github.com/154755 I know people hate mixins, but this approach would give us discoverability and a slightly terser syntax, without having to actually introduce new language syntax. And maybe if D ends up with enough of these mixins being used as standard, it'll spur Walter into adding macros. :D Examples from the code: struct S { mixin ( // Default accessor property with automatic private storage. Property!(int, "bar") // Public read-only w/ auto storage ~Property!(int, "baz", null, "private") // Public read-only with default ~Property!(int, "bop = 42", null, "private") // Read-only ~Property!(int, "qux", null, "-") // Fully custom; no auto storage created ~Property!(int, "zyz", q{ return 7; }, q{ // Note "magic" value argument writefln("Set zyz to: %s", value); }) // Fully custom with private setter and auto storage ~Property!(int, "gfh", q{ // Public here is optional public { return storage/100; } }, q{ private { storage = value*100; } }) ); }Ary Borenszweig wrote:This is pretty clean, and in keep with the opXxx approach. Actually how about defining property foo by defining opGet_foo and opSet_foo. AndreiMaybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like: int property foo(); // getter int property foo(int value); // setterMy proposal requires no new keywords and no new syntax: int getfoo(); // getter int setfoo(int); // setter
Jul 25 2009
On Fri, 24 Jul 2009 22:58:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Rainer Deyke wrote:I would be OK with defining properties any of these ways. Although the definition of properties is ugly, it's the usability and meaning which are most important. Using opGet and opSet is probably the better method, since nobody is going to name their normal members that way. In fact, I think C++.Net did something similar in earlier versions. Something like to call or define properties you defined the function get_propname and set_propname. -SteveAry Borenszweig wrote:This is pretty clean, and in keep with the opXxx approach. Actually how about defining property foo by defining opGet_foo and opSet_foo.Maybe what scares Walter is a whole new syntax for properties. If at least you could say which functions are properties and which are not, that would be a small change and it'll make it possible for other things. Something like: int property foo(); // getter int property foo(int value); // setterMy proposal requires no new keywords and no new syntax: int getfoo(); // getter int setfoo(int); // setter
Jul 26 2009
Steven Schveighoffer wrote:On Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:But when I suggest a restriction on properties, I get complaints that someone might want to have them do what functions do. So I fail to see what rule distinguishes them from functions, even for people.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person.It's the exact same reason + is not the concatenation operator. Semantically, making + concatenate two strings together would be completely unambiguous from adding two integers together because strings do not define addition, and integers do not define concatenation. From your own documentation, someone seeing "10" + 3 might think that he would get 13 or "103". Even if the compiler defines what "should" happen, and the rules are unambiguous, it looks incorrect to the user.Using + for concatenation is syntactically ambiguous with vector addition.
Jul 24 2009
"Walter Bright" <newshound1 digitalmars.com> wrote in message news:h4d9jt$1hq5$1 digitalmars.com...Steven Schveighoffer wrote:I'm not sure what restriction you're talking about, but here's the difference: Function: Abstracted to a Verb ("write" "sort" "play" "decompress") Property: Abstracted to a Noun/Adjective ("position" "width" "color" "turret" "ball") Variable: *Special case of Property*, where the *underlying storage* is never lazy at all and is always exactly the same as what's presented to the class's user. Here's another (psuedocode) way to describe the difference: Thing2D ball1, ball2; ball1.moveTo( [10, 7] ); // Function ball1.position = [10, 7]; // Property ball1.moveTo = [10, 7]; // Meaningless bullshit ball1.position( [10, 7] ); // Meaningless bullshit ball1.moveTo(ball2.position); // Sensible ball1.position = ball2.position; // Sensible ball1.moveTo(ball2.moveTo); // Meaningless bullshit ball1.position = ball2.moveTo; // Meaningless bullshitOn Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:But when I suggest a restriction on properties, I get complaints that someone might want to have them do what functions do. So I fail to see what rule distinguishes them from functions, even for people.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person.Are you saying that were it not for vector operations you would have used + for concatenation? If not, then you're dodging the point Steven is making.It's the exact same reason + is not the concatenation operator. Semantically, making + concatenate two strings together would be completely unambiguous from adding two integers together because strings do not define addition, and integers do not define concatenation. From your own documentation, someone seeing "10" + 3 might think that he would get 13 or "103". Even if the compiler defines what "should" happen, and the rules are unambiguous, it looks incorrect to the user.Using + for concatenation is syntactically ambiguous with vector addition.
Jul 25 2009
"Nick Sabalausky" <a a.a> wrote in message news:h4eg2c$sn8$1 digitalmars.com..."Walter Bright" <newshound1 digitalmars.com> wrote in message news:h4d9jt$1hq5$1 digitalmars.com...With that ball/moveTo/position stuff, I should also clarify that for most of the code/languages across my programming career (save for the occasional cases of deliberate obfuscation and blatanty bad coding standards...oh, and asm of course ;) ) up until D, things have pretty much always worked like this: IDENTIFIER PARENS: Verb IDENTIFIER: Noun/Adjective And especially now, that's becoming more and more the standard convention. (And yea, I'm sure there's a bunch of languages from the 80's and before that were completely different...)Steven Schveighoffer wrote:I'm not sure what restriction you're talking about, but here's the difference: Function: Abstracted to a Verb ("write" "sort" "play" "decompress") Property: Abstracted to a Noun/Adjective ("position" "width" "color" "turret" "ball") Variable: *Special case of Property*, where the *underlying storage* is never lazy at all and is always exactly the same as what's presented to the class's user. Here's another (psuedocode) way to describe the difference: Thing2D ball1, ball2; ball1.moveTo( [10, 7] ); // Function ball1.position = [10, 7]; // Property ball1.moveTo = [10, 7]; // Meaningless bullshit ball1.position( [10, 7] ); // Meaningless bullshit ball1.moveTo(ball2.position); // Sensible ball1.position = ball2.position; // Sensible ball1.moveTo(ball2.moveTo); // Meaningless bullshit ball1.position = ball2.moveTo; // Meaningless bullshitOn Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:But when I suggest a restriction on properties, I get complaints that someone might want to have them do what functions do. So I fail to see what rule distinguishes them from functions, even for people.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person.
Jul 25 2009
Walter Bright Wrote:Steven Schveighoffer wrote:The only thing that properties can't do that functions can is be called with parentheses. The only thing that functions cannot do that properties can is be called without parentheses (assuming properties are separated from functions) I fail to see any issues there. Where are these complaints you speak of? I've not seen any.On Fri, 24 Jul 2009 14:10:59 -0400, Walter Bright <newshound1 digitalmars.com> wrote:But when I suggest a restriction on properties, I get complaints that someone might want to have them do what functions do. So I fail to see what rule distinguishes them from functions, even for people.That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.If you delineate what can be called how, then you elminate syntax ambiguities from occurring, and eliminate bizarro cases of syntax. The difficulty is that the "human meaning" of a property is different than the human meaning of a function. To the compiler, they're all functions, so you as the compiler writer aren't seeing that they are different. I think we all agree that writefln = "hi"; makes absolutely no sense to a person. But it makes complete sense to the compiler, because it has no idea what the word "writefln" means to a person.OK, but assuming you didn't have vector addition (which you didn't have up until a few months ago), then how is this a different scenario than the property issue? Isn't it also ambiguous when you want to call a delegate/function returned from a property? Besides this, I like what another poster brought up better -- array indexing is the same as functions too, they take a single parameter, and return a value. So why do we have two different syntaxes for arrays and functions? Why do we have a special syntax for opIndex but no special syntax for properties? They're all functions, right? -SteveIt's the exact same reason + is not the concatenation operator. Semantically, making + concatenate two strings together would be completely unambiguous from adding two integers together because strings do not define addition, and integers do not define concatenation. From your own documentation, someone seeing "10" + 3 might think that he would get 13 or "103". Even if the compiler defines what "should" happen, and the rules are unambiguous, it looks incorrect to the user.Using + for concatenation is syntactically ambiguous with vector addition.
Jul 25 2009
Walter Bright wrote:That's my problem with properties as a distinct syntax - they don't have distinct uses or behaviors.You know, I don't believe I've seen you reply specifically to any of the good points about D's properties people have been mentioning around here. I believe the list I gave you in the 'big' subthread was fairly complete. Would you please tell us what you think about each point? I'll repeat that specific section of my reply here: --------------------Why not? Seriously, what is the semantic difference?There are many reasons. Some have been floating around this newsgroup this very day. * A reference to a function should mean exactly that: a reference to the function, for use in functional programming. Instead, just the name of a function now invokes a call. * In D, &foo returns a function-pointer, but that means that D is context sensitive, since its subexpression foo would return a property value. It is confusing. * What does D do if you have a property (p) that returns a delegate? Will the call p() return the delegate? Or will it call the delegate? * writefln = 5; This should just not be valid code. But it is. * Real Properties have many advantages over what looks like D's ad-hoc solution. They automatically document themselves as properties both to the programmer and to IDE's (see some other posts from today). The programmer may use them to overload certain operators and mutator functions that would speed up the program. Months ago there was a big thread about Real Properties. I myself offered a suggestion for their design. I don't remember if you ever responded. That's just a few reasons right there. D's properties lack elegance and they lack potential. -------------------- PS: I don't mean to gang up on you. You're just not making yourself clear on where you stand on these points and why. -- Michiel Helvensteijn
Jul 24 2009
On Fri, 24 Jul 2009 15:26:58 -0400, Michiel Helvensteijn <m.helvensteijn.remove gmail.com> wrote:PS: I don't mean to gang up on you. You're just not making yourself clear on where you stand on these points and why.This is typical Walter :) He'll argue the easy ones all day long, and stay silent on the harder-to-refute ones. Then one day, you'll see the feature you wanted suddenly and without warning appear in the compiler (I'm still holding my breath on a few). Not that this means properties are going to be one of those features, but still. With Walter, silence is usually all you get when he's coming around to your side :) It's a good strategy for someone who's word is almost law when it comes to D. You have to be careful what you say, flip-flopping around only leads to knee-jerk feature additions, more bikeshed discussions, and more people clammoring for feature additions (hey, you added this, why not that!). I have great respect for the balance he has to deal with between adding interesting features and keeping a sane spec. -Steve
Jul 24 2009
Steven Schveighoffer wrote:It's a good strategy for someone who's word is almost law when it comes to D. You have to be careful what you say, flip-flopping around only leads to knee-jerk feature additions, more bikeshed discussions, and more people clammoring for feature additions (hey, you added this, why not that!). I have great respect for the balance he has to deal with between adding interesting features and keeping a sane spec.I spent literally all day in this thread yesterday. Each reply I make spawns several replies from others. It's exponential. At some point, I have to just stop <g>.
Jul 24 2009
Michiel Helvensteijn wrote:That's just a few reasons right there. D's properties lack elegance and they lack potential.Let's start with: 1. What is a property? 2. How is that different from, say, a pure function?
Jul 24 2009
On Fri, Jul 24, 2009 at 2:44 PM, Walter Bright<newshound1 digitalmars.com> wrote:Michiel Helvensteijn wrote:""" Properties are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used as though they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily while still providing the safety and flexibility of methods. """ -- thanks MSDNThat's just a few reasons right there. D's properties lack elegance and they lack potential.Let's start with: 1. What is a property?2. How is that different from, say, a pure function?Properties behave semantically like fields, but are implemented like functions enabling them to do arbitrary calculation on the side when the field is read from or written to. Pure functions are totally different. First, half of the property syntax is about mutating a state. That's obviously not pure. And on the get() side its returning the value of a mutable state, so again, not pure. --bb
Jul 24 2009
Walter Bright wrote:Michiel Helvensteijn wrote:A property contains information describing some object, which may or may not be mutable.That's just a few reasons right there. D's properties lack elegance and they lack potential.Let's start with: 1. What is a property?2. How is that different from, say, a pure function?A pure function is a computation without side effects: - does not have to relate to any one object - a mutable counterpart may not make any sense - it cannot have any side effects while that may make sense even for a getter (lazy load for example) - it does not have to *describe* an object in the sense that a property does The mechanism may be exactly the same, but a property gives a big hint to the programmer (and tools) as to what kind of thing you are dealing with. Extremely dumb example, all very much the same going from less to more nice: color(corvette, Color.Red); assert(color(corvette) == Color.Red); corvette.color(Color.Red); assert(corvette.color() == Color.Red) corvette.color = Color.Red; assert(corvette.color == Color.Red);
Jul 24 2009
Walter Bright wrote:I agree with Bill's reply to this one. Again it appears you're avoiding those specific issues I mentioned. Quite blatantly, I might add. Many people have been asking you the same thing. Do you not have a answer? -- Michiel HelvensteijnThat's just a few reasons right there. D's properties lack elegance and they lack potential.Let's start with: 1. What is a property? 2. How is that different from, say, a pure function?
Jul 24 2009
Walter Bright wrote:Michiel Helvensteijn wrote:That's just a few reasons right there. D's properties lack elegance and they lack potential.Let's start with: 1. What is a property?A piece of state referred to by some name; state which is usually part of some object. Semantically the same as a field, except it may be more complex then just an address in memory. I'm going to fudge your next question a little... We've already established that pure functions won't cut it since they prevent you from doing lazy loads, or anything involving mutation (like tracking access counts). So let's pretend the question was:2. How is that different from, say, a function?Which has a more interesting answer. :) In terms of machine code, nothing. This isn't a question about functionality, in the end, it's a question of intent. To reiterate: something like Qt depends pretty heavily on properties being distinct from functions. For example: T foo(); T foo(T); Is foo a property or a function? It's impossible to tell. It could be a function with two overloads, one of which requires an argument, or it could be a getter/setter pair. This causes a few problems. The first of which, and the one that I think is the most important, is it cripples IDEs and other graphical tools. Another example: I'm in the planning stages for a graphical editor that snaps together components. I'd love to be able to just introspect an object at runtime and grab all the properties, but I can't. I cannot determine, for certain, which methods are properties and which are REALLY methods, so I'll probably end up doing something like this: class Blah : Component { mixin(properties("a", "b", "c")); } To identify them. Of course, this isn't much use for a general IDE, unless this sort of thing becomes a standard in the language, and even then it's pretty hideous. Another problem is the issue with leaving off parens. The canonical example being: struct Foo { int delegate() bar(); } You have to put in *two* sets of parens to call the result from bar, not one as might be assumed. There's also the argument for debuggers being able to automatically display properties; I think this one is fairly borderline since if I was writing a debugger, it would only *automatically* display the result of pure functions, property or not. Finally, there's a speculative argument in that the current arrangement limits properties to having a getter and/or a setter. Andrei made a comment a while back about needing three primitives for them to work properly; in the current system. --- So basically, the issues are not *really* technical; they all boil down to ambiguity in terms of interpretation, or clumsy corner cases. To speak of the technical implementation of properties, my comments on DIP4 basically recommends to implement "new style" properties almost EXACTLY THE SAME as current ones; the difference is that "new style" properties have slightly more information available about them. I hope all that helps, although I suspect I'm just rambling at this point. :)
Jul 24 2009
On Fri, 24 Jul 2009 21:36:53 -0400, Daniel Keep <daniel.keep.lists gmail.com> wrote:There's also the argument for debuggers being able to automatically display properties; I think this one is fairly borderline since if I was writing a debugger, it would only *automatically* display the result of pure functions, property or not.I agree with this. A property should only be callable by the debugger if it is pure. I don't think properties should be required to be pure, because pure functions are far too restrictive for properties. Note that in other debuggers which debug code that is fully runtime evaluating a property will result in an object change, so they must mark the property somehow. I think the other reasons for having property syntax are much more important than this. -Steve
Jul 26 2009
Walter Bright wrote:Then perhaps you can get rid of enum and have only immutable. Well, I'm sure you have valid reasons to keep it (like actual enumeration). But it would just seem worthwhile to try to unify them.Aren't immutable and enum the same thing? At least to the programmer?Not at all. How would you declare a type that is "pointer to immutable int" using an enum? Anyhow, there was a looong thread about this a year back or so.Contracts didn't hit paydirt, and so haven't gotten a lot of follow-on attention.This is too bad. It was one of the features that I liked most about D when I first started using it.and I never heard of ranking functions.Yeah, they're called something different everywhere. I've seen them called loop variants or binding functions. It's the expression that strictly decreases each iteration and always remains non-negative. The existence of such an expression proves the eventual termination of the loop.There are many reasons. Some have been floating around this newsgroup this very day. * A reference to a function should mean exactly that: a reference to the function, for use in functional programming. Instead, just the name of a function now invokes a call. * In D, &foo returns a function-pointer, but that means that D is context sensitive, since its subexpression foo would return a property value. It is confusing. * What does D do if you have a property (p) that returns a delegate? Will the call p() return the delegate? Or will it call the delegate? * writefln = 5; This should just *not* be valid code. But it is. * Real Properties have many advantages over what looks like D's ad-hoc solution. They automatically document themselves as properties both to the programmer and to IDE's (see some other posts from today). The programmer may use them to overload certain operators and mutator functions that would speed up the program. Months ago there was a big thread about Real Properties. I myself offered a suggestion for their design. I don't remember if you ever responded. That's just a few reasons right there. D's properties lack elegance and they lack potential.* No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?Aha. Then you may want to fix the documentation. http://d.puremagic.com/issues/show_bug.cgi?id=3204* No global properties: If I'm not mistaken, global functions can't be properties.int foo() { return 3; } void main() { int x = foo; } works.Not if commutativity of the * operator is fixed. The documentation states that * is commutative, which in fact for integers it is. So if I overload * for matrices, for all the guarantees the docs give me, a D compiler might choose to swap the operands around (perhaps to get some memory alignment advantage), and the returned matrix would be incorrect.I believe this is completely controllable with D.Arithmetic like operations like matrix multiplication (which is not commutative)?* Operator overloading (no fine control over comparison operators,> fixed commutativity, This is deliberate. Operator overloading should be restricted to implementing arithmetic like operations on objects, not completely different things like what iostreams, Spirit and Boost::regex do.Well, I suggest that there be NO reverse overloads, that an overload should be possible in the global scope with the class giving it access to its private members (C++ uses 'friend', but there must be more elegant ways), lifting the 'this' restriction that prompted reverse overloads. I don't know exactly what Koenig Lookup is, but from what I read on Wikipedia, it involves arbitrary access to other namespaces, which seems unnecessary. Otherwise it sounds like regular function overloading based on its parameter types, which D supports, of course. Though I haven't read it through in detail.Perhaps you misunderstand. I was referring to the algorithm that first checks for a complete match, then tries the 'reverse overload', then tries the commutative call.I did understand it. The alternative is Koenig Lookup, and the reason for its existence. Reverse operator overloading is a bit awkward, but the awkwardness is restricted to the class in which it appears. ADL (Koenig Lookup) spreads awkwardness everywhere.I don't know a compelling use-case either. But that doesn't mean there isn't any. Nor are there any real dangers. Arbitrarily restricting the possibilities of D doesn't seem like the right way to go.Oops, you're right. Here's an old thread about it: http://www.digitalmars.com/d/archives/digitalmars/D/18153.html I can't recall ever seeing anyone use it, though. Until there's a compelling use case for it, not just it being a nice idea, I'll stick with my belief it's a bad idea.For && and ||, they are "short circuit" operators, and how that would sensibly interact with operator overloading I have no idea.See my comments above about lazy parameter evaluation. I suggest that those operators are defined with a lazy second parameter for bools, and programmers should be allowed to overload them for other types as they please.I know of no language that allows overloading && and ||.C++ does. ! too.See my link just below. If tuples are available in the core language just like that, people will feel much more comfortable using them in any situation.You cannot get a dedicated syntax with library support.Of course that's true, but why is a dedicated syntax better than Tuple!( ...) ?http://code.google.com/p/mist/wiki/TuplesI've mentioned I'm working on a programming language myself. I haven't mentioned its name here, because I didn't think it'd be appropriate. But with your permission I can post a link to a page describing my tuples.Sure.You can use static asserts to, at compile time, check the result of any computation, including function calls, that the compiler is able to execute at compile time. It sounds perfectly usable as unit tests to me, and in fact I do use static assert that way.Can you allocate stuff on the heap? If not, you can't do proper unit testing at compile-time. Perhaps I should have said that the unit-tests should be run automatically just after compilation and they should not be part of the program executable. They don't actually need to run 'at compile-time'.It's not. And you understand that the modulo thing is only a symptom, right? I've found another mistake by accident just today. See the issue report I filed.Yes, but 'pretty clear' does not a spec make. I refer you to our earlier divide/modulo discussion.We're going to fix the modulo thing. But the C++ standard leaves it implementation defined. How is that better?Sure, the D spec has gaps in it. But the C++ standard also has large gaps of uselessness in it.I agree. But at least you can count on C++ to do as specified. Where it doesn't give any guarantees, it specifies that also. With D it's mostly guesswork and experimentation. -- Michiel Helvensteijn
Jul 23 2009
Michiel Helvensteijn wrote:That's not what the documentation means. * is only 'default commutative'. If a.opMul(b) is defined, by default you get b * a == a*b. To prevent this behaviour, you just need to define a.opMul_r(b), or b.opMul(a). (The documenation could be a bit clearer on this).Not if commutativity of the * operator is fixed. The documentation states that * is commutative, which in fact for integers it is. So if I overload * for matrices, for all the guarantees the docs give me, a D compiler might choose to swap the operands around (perhaps to get some memory alignment advantage), and the returned matrix would be incorrect.I believe this is completely controllable with D.Arithmetic like operations like matrix multiplication (which is not commutative)?* Operator overloading (no fine control over comparison operators,> fixed commutativity, This is deliberate. Operator overloading should be restricted to implementing arithmetic like operations on objects, not completely different things like what iostreams, Spirit and Boost::regex do.
Jul 24 2009
Walter Bright wrote:Michiel Helvensteijn wrote:...The major point about properties is imo not a semantic issue at all, it's about signalling the intention (much like the debug version statement is). This is also key to integration with tools like IDE and it's usefulness in gui programming.* No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?
Jul 23 2009
Walter Bright, el 23 de julio a las 12:11 me escribiste:When I see this, I think about this: for (std::vector<int>::const_iterator i = v.begin(); i != v.end(); ++i) { int x = *i; ... } Why is foreach (x; v) ... better than the former? The problem is, if is hard to write, or ugly to read, people won't use it, or will use it less. In Python tuples are easy to read and write, so people use them everywhere and they are really useful (especially for FP-style programming, where is more common to return multple values). I think that library tuple *implementation* is a great idea (like library dynamic and associative arrays implementations), but not having support in the language for tuples is bad (like it will be not to have dynamic and associative arrays). I think the 3 are very fundamental types and deserves language support. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- <original> [Penis Uptime: 2days 13hrs 59mins 35secs] <Yapa> viagra? :) <original> yea, 20 pillsOf course that's true, but why is a dedicated syntax better than Tuple!( ...) ?You cannot get a dedicated syntax with library support.* Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples)The flattening thing is a problem. The rest can be done with better library support.
Jul 23 2009
Leandro Lucarella wrote:The problem is, if is hard to write, or ugly to read, people won't use it, or will use it less. In Python tuples are easy to read and write, so people use them everywhere and they are really useful (especially for FP-style programming, where is more common to return multple values).That is a good point. I won't say I'm convinced for the tuple case <g>, but it is a good argument.
Jul 23 2009
Walter Bright, el 23 de julio a las 17:42 me escribiste:Leandro Lucarella wrote:I can't believe it, I actually made Walter think something twice! =P -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- CAMPAÑA POR LA PAZ: APLASTARON JUGUETES BÉLICOS -- Crónica TVThe problem is, if is hard to write, or ugly to read, people won't use it, or will use it less. In Python tuples are easy to read and write, so people use them everywhere and they are really useful (especially for FP-style programming, where is more common to return multple values).That is a good point. I won't say I'm convinced for the tuple case <g>, but it is a good argument.
Jul 24 2009
Walter Bright wrote:Of course that's true, but why is a dedicated syntax better than Tuple!( ...) ?Why is dedicated syntax for comma expressions better than commaExpr(...) ? I take it most folks on this NG would prefer to have shorter syntax for tuples instead the virtually never used comma expressions. Other than that, you need Tuple!(...) for type tuples, some sorta STuple!(...) for struct-tuples (so they can be nested and passed around properly) and makeTuple(...) for struct-tuple instances. Comma expressions don't even have to be first-class members of the language: ---- import tango.io.Stdout; T[$-1] commaExpr(T ...)(lazy T t) { foreach (x; t[0..$-1]) { auto y = x; } return t[$-1]; } T[0] revCommaExpr(T ...)(lazy T t) { foreach_reverse (x; t[1..$]) { auto y = x; } return t[0]; } void main() { { int x; int y = revCommaExpr(x += 123, x *= 2, Stdout.formatln("{}", x), Stdout("omg").newline); assert (y == 123); } { int x; commaExpr(x += 123, x *= 2, Stdout.formatln("{}", x), Stdout("omg")).newline; } } ---- Output: omg 0 246 omg ---- -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Jul 23 2009
On Thu, Jul 23, 2009 at 10:49:49PM +0100, Tom S wrote:Why is dedicated syntax for comma expressions better than commaExpr(...)?What do you propose we do about the commas in loops? Breaking them would be a pretty big change to the C folks. With the naked comma tuple, how do you pass them to a function? void func(Tuple!(int, int) a, int b); Is that just the same as: void func(int a, int b, int c); You'd call them the same way without the tuple decoration :S It might be my years of C bias, but the naked tuples just look wrong. -- Adam D. Ruppe http://arsdnet.net
Jul 23 2009
Adam D. Ruppe wrote:It might be my years of C bias, but the naked tuples just look wrong.There are ways -- elegant ways, I believe -- to make it work. Would you look at this page and give me your opinion? http://code.google.com/p/mist/wiki/Tuples I'm not sure if it can ever work for D, to be honest. There may be too many differences between the two languages. -- Michiel Helvensteijn
Jul 23 2009
On Fri, Jul 24, 2009 at 12:03:37AM +0200, Michiel Helvensteijn wrote:Would you look at this page and give me your opinion?Looking at it quickly, the big difference seems to be you leave the tuple word off, and use them in more places. Is Tuple!(int, bool) A = tuple(a, b) really that much worse than: (int, bool) A = (a, b) ? Better yet, of course is: auto A = tuple(a, b); By keeping the tuple word there, it is no longer conflicting with my C expectations, but seems to be just as useful as your proposal. -- Adam D. Ruppe http://arsdnet.net
Jul 23 2009
Adam D. Ruppe wrote:By keeping the tuple word there, it is no longer conflicting with my C expectations, but seems to be just as useful as your proposal.Hm. Then I believe you haven't read the whole thing. (That's ok, it does go on for a while.) Yes, much of the appeal is in the shorter syntax. But some of the features proposed even require that no 'tuple' keyword is used. Looking like C is not the be-all and end-all of programming languages. Mist tries to follow mathematical notation wherever possible. This has had other implications, like using <- for assignment and = for equality. -- Michiel Helvensteijn
Jul 23 2009
On Fri, Jul 24, 2009 at 12:37:42AM +0200, Michiel Helvensteijn wrote:Hm. Then I believe you haven't read the whole thing.Yeah, I just briefly skimmed it. I'll have to go back to it for a full read when I have a little more time.Looking like C is not the be-all and end-all of programming languages.For a language like D, which hopes to hold on to C programmers, it is very important. We're an obstinate bunch, set in our ways. I remember the first time I saw D: I dismissed it because the import statement looked "too Javaish" and didn't come back until a year or two later. A change like this would just be too weird, and would surely alienate some of the intended audience before they get past the first look. -- Adam D. Ruppe http://arsdnet.net
Jul 23 2009
Adam D. Ruppe wrote:On Fri, Jul 24, 2009 at 12:03:37AM +0200, Michiel Helvensteijn wrote:It's not much worse, but it's not everything that's to tuples. Here's one more example:Would you look at this page and give me your opinion?Looking at it quickly, the big difference seems to be you leave the tuple word off, and use them in more places. Is Tuple!(int, bool) A = tuple(a, b) really that much worse than: (int, bool) A = (a, b) ? Better yet, of course is: auto A = tuple(a, b);int a, b;----a, b = 2, 3;Can't do it with tuple(a, b) = tuple(2, 3); One would have to create yet another helper function, e.g.ptuple(&a, &b) = tuple(2, 3);Or perhaps something with 'ref' instead of pointers, but I remember it being buggy with tuples, and might be too dangerous, since you wouldn't see that you're passing pointers around -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Jul 23 2009
On Thu, Jul 23, 2009 at 11:49:29PM +0100, Tom S wrote:It's not much worse, but it's not everything that's to tuples. Here's one more example:Why would you ever want to do that when you have: a = 2; b = 3; I see people ask why would you ever want the existing comma operator, when you can just separate it into two lines, and the replacement use could also just be separated into two lines. The swap function I've seen tossed around could just be swap(x,y) instead of y,x = x,y too. A fancier rearrange could be done with a template, so: (x, y, z) = (z, y, z) becomes: rearrange(x, y, z, z, y, x); I could see a function returning it as being potentially useful for the x,y case: Tuple!(int, int) getPoint() { return tuple(x, y); } ... x, y = getPoint(); But, a better way to do this would be: Tuple!(int, "x", int, "y") getPoint() { return tuple(x, y); } ... auto p = getPoint(); // work with p.x and p.y It is two brief lines longer to copy them to a local x and y if you want to. -- Adam D. Ruppe http://arsdnet.netint a, b;----a, b = 2, 3;
Jul 23 2009
On Thu, 23 Jul 2009 21:22:03 -0400, Adam D. Ruppe wrote:I could see a function returning it as being potentially useful for the x,y case: Tuple!(int, int) getPoint() { return tuple(x, y); } ... x, y = getPoint(); But, a better way to do this would be: Tuple!(int, "x", int, "y") getPoint() { return tuple(x, y); } ... auto p = getPoint(); // work with p.x and p.y It is two brief lines longer to copy them to a local x and y if you want to.Thanks for the tutorial, expect to see it on Wiki4D within a year :D
Jul 23 2009
On Fri, Jul 24, 2009 at 01:38:30AM +0000, Jesse Phillips wrote:Thanks for the tutorial, expect to see it on Wiki4D within a year :DThis actually doesn't /quite/ work, since the tuple returned by tuple() has unnamed fields, which is a different type than the one with named fields. Gah. This works though: auto getPoint() { return Tuple!(int, "x", int, "y")(5, 2); } That's getting a wee bit ugly even for my likes, but is the best way for correctness and ease of use on the calling end. Or Tuple!(int, int) getPoint() { return tuple(5,2); } That works, but then you have to address the return value as: auto p = getPoint(); p.field[0] == 5 p.field[1] == 2 Still, easy enough to say: auto x = p.field[0]; auto y = p.field[1]; x == 5 y == 2 -- Adam D. Ruppe http://arsdnet.net
Jul 23 2009
On Thu, 23 Jul 2009 22:56:44 -0400, Adam D. Ruppe wrote:On Fri, Jul 24, 2009 at 01:38:30AM +0000, Jesse Phillips wrote:Thanks, truth be told I don't know why that first one works. But the second looks completely reasonable.Thanks for the tutorial, expect to see it on Wiki4D within a year :DThis actually doesn't /quite/ work, since the tuple returned by tuple() has unnamed fields, which is a different type than the one with named fields. Gah. This works though: auto getPoint() { return Tuple!(int, "x", int, "y")(5, 2); } That's getting a wee bit ugly even for my likes, but is the best way for correctness and ease of use on the calling end. Or Tuple!(int, int) getPoint() { return tuple(5,2); } That works, but then you have to address the return value as: auto p = getPoint(); p.field[0] == 5 p.field[1] == 2 Still, easy enough to say: auto x = p.field[0]; auto y = p.field[1]; x == 5 y == 2
Jul 23 2009
Adam D. Ruppe, el 23 de julio a las 22:56 me escribiste:On Fri, Jul 24, 2009 at 01:38:30AM +0000, Jesse Phillips wrote:And you still think that's not remarkably worse than something like: (int, int) getPoint() { return (5, 2); } auto (x, y) = getPoint(); I really think that's the difference between happily using tuples or curse them for the rest of your life :) I don't think comma expressions should be used for tuples (I don't care much either), but you can add support to the language without breaking them using something like (1, 2, 3) or ![ 1, 2, 3 ] or whatever. But you should support multple assignment, for example. If you don't, you don't have real tuple support, just a toy tuple emulation. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- We're rotten fruit We're damaged goods What the hell, we've got nothing more to lose One gust and we will probably crumble We're backdriftersThanks for the tutorial, expect to see it on Wiki4D within a year :DThis actually doesn't /quite/ work, since the tuple returned by tuple() has unnamed fields, which is a different type than the one with named fields. Gah. This works though: auto getPoint() { return Tuple!(int, "x", int, "y")(5, 2); } That's getting a wee bit ugly even for my likes, but is the best way for correctness and ease of use on the calling end. Or Tuple!(int, int) getPoint() { return tuple(5,2); } That works, but then you have to address the return value as: auto p = getPoint(); p.field[0] == 5 p.field[1] == 2 Still, easy enough to say: auto x = p.field[0]; auto y = p.field[1]; x == 5 y == 2
Jul 24 2009
On Fri, 24 Jul 2009 12:30:23 -0300, Leandro Lucarella wrote:Adam D. Ruppe, el 23 de julio a las 22:56 me escribiste:I would say it isn't remarkably worse. The other one though, that was quite a mess.Tuple!(int, int) getPoint() { return tuple(5,2); } That works, but then you have to address the return value as: auto p = getPoint(); p.field[0] == 5 p.field[1] == 2 Still, easy enough to say: auto x = p.field[0]; auto y = p.field[1]; x == 5 y == 2And you still think that's not remarkably worse than something like: (int, int) getPoint() { return (5, 2); } auto (x, y) = getPoint();I really think that's the difference between happily using tuples or curse them for the rest of your life :) I don't think comma expressions should be used for tuples (I don't care much either), but you can add support to the language without breaking them using something like (1, 2, 3) or ![ 1, 2, 3 ] or whatever. But you should support multple assignment, for example. If you don't, you don't have real tuple support, just a toy tuple emulation.Tuples have nothing to do with multiple assignment, it is just something languages tend to provide.
Jul 24 2009
Jesse Phillips, el 25 de julio a las 03:38 me escribiste:It has, providing tuples without that generally doesn't need language support, like D or C++ tuples. When you have multiple assignment, you can fully use the power of tuples, if not, it's just syntax sugar for structs, or some kind of limited list. Tuples are much more useful when are a *language construct*. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Dale tu mano al mono, pero no el codo, dado que un mono confianzudo es irreversible. -- Ricardo Vaporeso. La Reja, Agosto de 1912.But you should support multple assignment, for example. If you don't, you don't have real tuple support, just a toy tuple emulation.Tuples have nothing to do with multiple assignment, it is just something languages tend to provide.
Jul 25 2009
Leandro Lucarella wrote:It has, providing tuples without that generally doesn't need language support, like D or C++ tuples. When you have multiple assignment, you can fully use the power of tuples, if not, it's just syntax sugar for structs, or some kind of limited list.From the Boost.Tuple documentation: int i; char c; double d; tie(i, c, d) = make_tuple(1,'a', 5.5); std::cout << i << " " << c << " " << d; So C++ tuples *do* support multiple assignment, even without language support. Still not as nice as the Python syntax, though. -- Rainer Deyke - rainerd eldwood.com
Jul 25 2009
On Sat, Jul 25, 2009 at 01:20:33PM -0600, Rainer Deyke wrote:I think I like that. -- Adam D. Ruppe http://arsdnet.netFrom the Boost.Tuple documentation:int i; char c; double d; tie(i, c, d) = make_tuple(1,'a', 5.5); std::cout << i << " " << c << " " << d; So C++ tuples *do* support multiple assignment, even without language support. Still not as nice as the Python syntax, though.
Jul 25 2009
Rainer Deyke, el 25 de julio a las 13:20 me escribiste:Leandro Lucarella wrote:But you have to split declaration from initialization. That's not nice. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Yo soy Peperino Mártir Sanito, yo soy aquel, que come los flanes serenito. -- Peperino PómoroIt has, providing tuples without that generally doesn't need language support, like D or C++ tuples. When you have multiple assignment, you can fully use the power of tuples, if not, it's just syntax sugar for structs, or some kind of limited list.From the Boost.Tuple documentation: int i; char c; double d; tie(i, c, d) = make_tuple(1,'a', 5.5); std::cout << i << " " << c << " " << d; So C++ tuples *do* support multiple assignment, even without language support. Still not as nice as the Python syntax, though.
Jul 25 2009
On Sat, Jul 25, 2009 at 02:15:00PM -0300, Leandro Lucarella wrote:if not, it's just syntax sugar for structs, or some kind of limited list.Interestingly, I've been looking at tuples almost entirely as "anonymous structs", if you will. Perhaps this is another bias preventing me from seeing the big advantage of the other syntax. -- Adam D. Ruppe http://arsdnet.net
Jul 25 2009
Adam D. Ruppe wrote:(...) It is two brief lines longer to copy them to a local x and y if you want to.Remember delegate literals? They were just a few more tokens, but it wasn't until the shorthand syntax was introduced that everyone started using them. I mean, how hard is it to type the extra 'delegate' and perhaps a return type after it... -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Jul 23 2009
On Thu, Jul 23, 2009 at 3:41 PM, Adam D. Ruppe<destructionator gmail.com> wrote:On Fri, Jul 24, 2009 at 12:03:37AM +0200, Michiel Helvensteijn wrote:Uh, yes. Yes it is. But I have to say I'm always amazed what clutter some people are apparently willing to put up with when I look at just about any page of MSDN. --bbWould you look at this page and give me your opinion?Looking at it quickly, the big difference seems to be you leave the tuple word off, and use them in more places. Is Tuple!(int, bool) A = tuple(a, b) really that much worse than: (int, bool) A = (a, b) ?
Jul 23 2009
On Thu, Jul 23, 2009 at 05:53:35PM -0700, Bill Baxter wrote:Uh, yes. Yes it is. But I have to say I'm always amazed what clutter some people are apparently willing to put up with when I look at just about any page of MSDN.And I'm amazed at the illegibility some people are apparently willing to put up with whenever I look at just about any scripting language code. (Or regular expressions, my God!) I certainly wouldn't go into Java territory for bondage and discipline, but some amount of verbosity helps keep me sane.--bb-- Adam D. Ruppe http://arsdnet.net
Jul 23 2009
Adam D. Ruppe:Why is dedicated syntax for comma expressions better than commaExpr(...)? What do you propose we do about the commas in loops? Breaking them would be a pretty big change to the C folks.<Disallowing bad usages of commas is a starting point. for() can become a special case. Handy syntax for tuple unpacking is useful in many situations, look at Python code. Bye, bearophile (Late answer, sorry, I was away)
Jul 27 2009
On Thu, Jul 23, 2009 at 6:10 PM, Adam D. Ruppe<destructionator gmail.com> wrote:What do you propose we do about the commas in loops? Breaking them would be a pretty big change to the C folks.It's trivial to allow a comma-separated list of expressions in the for loop header. If Pythonic tuple syntax were used (i.e. parens required), there would be no parsing ambiguity.
Jul 23 2009
no overloading of !, &&, ||,What bothers me about overloading && and || is they are control flow constructs, not really "operators". For example, ?: is also a control flow operator, and it sensibly isn't overloadable in C++. What if you could overload if..else.. statements? I'm sure someone somewhere could find a use for that, but it's still not a good idea.
Jul 23 2009
Walter Bright wrote:Ask downs about that one :3no overloading of !, &&, ||,What bothers me about overloading && and || is they are control flow constructs, not really "operators". For example, ?: is also a control flow operator, and it sensibly isn't overloadable in C++. What if you could overload if..else.. statements? I'm sure someone somewhere could find a use for that, but it's still not a good idea.
Jul 24 2009
On Wed, Jul 22, 2009 at 5:10 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:D just doesn't offer enough improvements over C++ to make it worthwhile switching over. Its design is not very adventurous, keeping simply too close to that of the C family, making it look like Yet Another C Language. I believe simply filling in the gaps of C++ wasn't enough to take over the world. There should have been a greater change.Ha. Had D differed *too* much from C++, then we'd run the risk of scaring off the C++ snobs simply because it wasn't familiar enough to them. You can never please C++ users with another language. Let's not get hung up on attracting them.
Jul 22 2009
Jarrett Billingsley wrote:Ha. Had D differed *too* much from C++, then we'd run the risk of scaring off the C++ snobs simply because it wasn't familiar enough to them.It's a good point. Radically different languages tend to fail simply because few are willing to expend the effort to learn it. This is why Haskell will never catch on.You can never please C++ users with another language. Let's not get hung up on attracting them.C++ will be around and will be used as long as any of us are alive, no matter what. It's just a fact of life.
Jul 22 2009
Wed, 22 Jul 2009 16:20:36 -0700, Walter Bright thusly wrote:Jarrett Billingsley wrote:Do you think it is the syntax or the semantics that is the cause? D is getting closer and closer to languages like Haskell. You can fit in many of the missing features without a sweat, but some fundamental parts of the languages already are contradictory. Some ideas: add tuples, algebraic data types, higher order types, existential and universal quantification, dynamic types, pattern matching, type classes, monad comprehensions, built-in currying, and guards. Maybe you don't see it as a problem yet, but D seems to suffer from serious featuritis; the philosophy seems to be: if some feature is implementable but yet unimplemented, it will be implemented. More features creep in until the language sinks. Isn't it too early to state whether Haskell will never catch on? Will D ever catch on? Both communities have grown since the births of the languages.Ha. Had D differed *too* much from C++, then we'd run the risk of scaring off the C++ snobs simply because it wasn't familiar enough to them.It's a good point. Radically different languages tend to fail simply because few are willing to expend the effort to learn it. This is why Haskell will never catch on.
Jul 29 2009
"Michiel Helvensteijn" <m.helvensteijn.remove gmail.com> wrote in message news:h47v8p$131i$1 digitalmars.com...D just doesn't offer enough improvements over C++ to make it worthwhile switching over.Even as a former die-hard C/C++ user, I've never really understood this argument. But, I'm not in the "you have to try it / sum of it's parts" camp either... Better is just plain better. If you've got two things available, and one is better, it just doesn't make any sense to stick with the worse one if the only reason to do so is inertia. That would be plain laziness. All of the following *individually* (ie, not just as a lump sum) are things for which I've always considered well worth leaving C/C++ in the history books where it belongs: - No separate header/implementation files. (IMO, the king of all language anachronisms.) - Non-null-terminated, slicable strings. - Strong typing (Unless things have changed since I last looked, I refuse to accept C/C++ as *truly* strong-typed. Hell, most modern dynamic languages have more right to be called strongly-typed than C/C++.) - True delegates and function literals. - A sensible foreach instead of that horrid stl iterator mess. (And this opinion of mine was formed long before Andrei's ranges.) - Metaprogramming that isn't a kludge (I'm looking at both the C preprocessor and the use of C++'s templates for anything beyond mere generics). - The availability of build tools that make manual dependency-tracking (not to mention those god-awful "*make" programs) obsolete. - "finally" (Or does C++ have this now too?) which fixes a fatal flaw in old-style exception handling (not to mention scope guards which even make "finally" look primitive, at least where applicable). If you have any of these available, why *not* use them? Sure, D has it's well-known issues, but they're nothing compared to any of the above problems with C/C++. Hell, the last few times I used C/C++, the *only* reason was because it was the only viable systems language I was aware of.
Jul 22 2009
Nick Sabalausky wrote:All of the following *individually* (ie, not just as a lump sum) are things for which I've always considered well worth leaving C/C++ in the history books where it belongs:And if D had just one of these features, plus all of the useful features of C++, then I would be using D instead of C++. But every time I find that a useful C++ idiom has no equivalent in D (and every time D introduces a new wart on top of the ones it inherits from C++), I am knocked back into C++ land. -- Rainer Deyke - rainerd eldwood.com
Jul 22 2009
Nick Sabalausky wrote:Better is just plain better. If you've got two things available, and one is better, it just doesn't make any sense to stick with the worse one if the only reason to do so is inertia. That would be plain laziness.It does take time and effort to learn a new tool, and that effort needs to be less than the expected gain.All of the following *individually* (ie, not just as a lump sum) are things for which I've always considered well worth leaving C/C++ in the history books where it belongs: - No separate header/implementation files. (IMO, the king of all language anachronisms.) - Non-null-terminated, slicable strings. - Strong typing (Unless things have changed since I last looked, I refuse to accept C/C++ as *truly* strong-typed. Hell, most modern dynamic languages have more right to be called strongly-typed than C/C++.) - True delegates and function literals. - A sensible foreach instead of that horrid stl iterator mess. (And this opinion of mine was formed long before Andrei's ranges.) - Metaprogramming that isn't a kludge (I'm looking at both the C preprocessor and the use of C++'s templates for anything beyond mere generics). - The availability of build tools that make manual dependency-tracking (not to mention those god-awful "*make" programs) obsolete. - "finally" (Or does C++ have this now too?) which fixes a fatal flaw in old-style exception handling (not to mention scope guards which even make "finally" look primitive, at least where applicable).My experience with C++ people sticking with it is they are so used to the problems they no longer see them. To me it's like the mess in one's house. One doesn't notice it until going on a vacation (i.e. learning a another language), having one's hotel room cleaned every day, then coming home and suddenly seeing how untidy it is <g>.If you have any of these available, why *not* use them? Sure, D has it's well-known issues, but they're nothing compared to any of the above problems with C/C++. Hell, the last few times I used C/C++, the *only* reason was because it was the only viable systems language I was aware of.The bizarre arguments I've seen are along the lines of "I don't want to use D because although it has X and Y which I love, it doesn't have Z doesn't have X, Y, or Z.
Jul 22 2009
Walter Bright wrote:My experience with C++ people sticking with it is they are so used to the problems they no longer see them. To me it's like the mess in one's house. One doesn't notice it until going on a vacation (i.e. learning a another language), having one's hotel room cleaned every day, then coming home and suddenly seeing how untidy it is <g>.I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of new features thrown in without rhyme or reason". D is many things, but a simple and elegant language it is not. (This is not a major problem to me, really. I can live with messy languages. I can live with C++. But to think that D is a massive improvement in this area requires a special sort of perspective.) The reason I have stuck with C++ despite its (massive, obvious) flaws is that it has a couple of really nice and useful features that very few other languages have even attempted to match. D is the only language I know that even tries, although it still falls short in many areas. -- Rainer Deyke - rainerd eldwood.com
Jul 22 2009
Rainer Deyke wrote:I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of new features thrown in without rhyme or reason". D is many things, but a simple and elegant language it is not. (This is not a major problem to me, really. I can live with messy languages. I can live with C++. But to think that D is a massive improvement in this area requires a special sort of perspective.)One measure of messy language semantics is the messiness of the compiler code needed to deal with it. D is a pretty clean language in comparison. <g> Another way is measuring the change in source code size. I get about a 30% reduction when translating C++ code more or less directly to D. Yes, I think it is a massive improvement over C++ in simplicity and elegance. But if you try to write C++ code in D, you won't see as much of that as you would after being more used to the D way of doing things. For example, my early C code looked an awful lot like Fortran! It took a while before I used the language in a style that was natural for C. My first years of C++ code also looked a lot like just plain old C (in fact, it arguably still does).The reason I have stuck with C++ despite its (massive, obvious) flaws is that it has a couple of really nice and useful features that very few other languages have even attempted to match. D is the only language I know that even tries, although it still falls short in many areas.Fair enough. What are those two features?
Jul 23 2009
Walter Bright wrote:Rainer Deyke wrote:1. C++'s object model, complete with polymorphic value types, deterministic destructors, arbitrary copy constructors, and optional lack of default constructor. D's structs come close, but I think the class/struct split hurts D more than it helps. And, yes, C++ has a lot of room for improvement here. 2. Templates. And this is one area that D improves in a major way. I love static if. -- Rainer Deyke - rainerd eldwood.comThe reason I have stuck with C++ despite its (massive, obvious) flaws is that it has a couple of really nice and useful features that very few other languages have even attempted to match. D is the only language I know that even tries, although it still falls short in many areas.Fair enough. What are those two features?
Jul 23 2009
Rainer Deyke wrote:Walter Bright wrote:What designs make good use of polymorphic value types?Rainer Deyke wrote:1. C++'s object model, complete with polymorphic value types,The reason I have stuck with C++ despite its (massive, obvious) flaws is that it has a couple of really nice and useful features that very few other languages have even attempted to match. D is the only language I know that even tries, although it still falls short in many areas.Fair enough. What are those two features?deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.D's structs come close, but I think the class/struct split hurts D more than it helps. And, yes, C++ has a lot of room for improvement here.How does the class/struct split? I think it's an enormous source of confusion for C++. C++ lore clarifies that you must decide in day one whether a class is meant to be polymorphic or monomorphic. Unfortunately that can't be expressed in the language, hence the weird cases with deriving from std::vector or getting polymorphic values unceremoniously sliced. Avoiding such mistakes are important things that C++ users must learn because there's nothing in the language stopping them from doing such nonsensical things; D very elegantly breaks that pattern by defining the language to only allow meaningful constructs. Who says the class/struct situation is worse off in D than in C++ either doesn't know C++ or knows C++ too well. Andrei
Jul 23 2009
Andrei Alexandrescu wrote:Rainer Deyke wrote:In a way, that's a loaded question, since C++ classes don't stay polymorphic when passed around by value. Actual polymorphic value types that stay polymorphic when copied would be much more useful. However, even the limited polymorphic value types of C++ are useful. Let's see: - Implementation inheritance of value types, even without actual polymorphism, is useful. See, for example, the curiously recurring template pattern (and all of its uses). And, yes, you can achieve similar results in D by using template mixins, but this is a specialized mechanism where C++ manages to do with the same generalized mechanism used for polymorphism and interface inheritance. I use inheritance of value types all the time. - Polymorphic references to value types are often useful. D has references to value types (in the form of 'ref' parameters and pointers) but these are not polymorphic. As an example, I would name the standard C++ iostream. They're value types (non-copyable for the most part, but stored directly instead of as pointers, with RAII), but they're often passed around as polymorphic references. I use polymorphic references to value types occasionally. - C++ makes a clear distinction between a reference and the thing being referenced. Even if value types and polymorphism were mutually exclusive, this distinction would be useful. All types are consistently treated as value types, even those types that reference another object. I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'. I *like* having to write 'p->f();' instead of 'p.f();'. It keeps my code clearly and more explicit. - C++ does not have separate rules for value types and reference types. All types are implicitly value types; values of all types can be placed on the heap. This simplifies the language by having just one set of rules instead of separate rules for classes and structs. Again, this unification would be useful even if it was an error to declare a variable of a polymorphic type as a direct variable.1. C++'s object model, complete with polymorphic value types,What designs make good use of polymorphic value types?There are things that copy constructors can do that the post-blit operator can't do. Also, unless I am mistaken, D can move value types around in memory at will, which also invalidates designs that are useful in C++.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.How does the class/struct split? I think it's an enormous source of confusion for C++. C++ lore clarifies that you must decide in day one whether a class is meant to be polymorphic or monomorphic. Unfortunately that can't be expressed in the language, hence the weird cases with deriving from std::vector or getting polymorphic values unceremoniously sliced. Avoiding such mistakes are important things that C++ users must learn because there's nothing in the language stopping them from doing such nonsensical things; D very elegantly breaks that pattern by defining the language to only allow meaningful constructs.On the contrary, the default in C++ is that a class can be used both as a value type and through a pointer as a reference type. Even in D, value types can be turned into value types Yes, when you copy class instances, it might be a bad idea to use the class as a base class. And conversely, if you use the class as a base class, it might be a bad idea to pass around instances of the class by value. It would be easy to forbid both of these at the language level, and almost as easy to fix them by creating non-slicing polymorphic value types. But the class/struct split in D goes much deeper than that. -- Rainer Deyke - rainerd eldwood.com
Jul 23 2009
Rainer Deyke wrote:- Implementation inheritance of value types, even without actual polymorphism, is useful. See, for example, the curiously recurring template pattern (and all of its uses).You can do this with 'alias this'.And, yes, you can achieve similar results in D by using template mixins, but this is a specialized mechanism where C++ manages to do with the same generalized mechanism used for polymorphism and interface inheritance.It should be a different mechanism to show that it is a very different thing. Value types aren't polymorphic and shouldn't look like they are.I use inheritance of value types all the time. - Polymorphic references to value types are often useful. D has references to value types (in the form of 'ref' parameters and pointers) but these are not polymorphic. As an example, I would name the standard C++ iostream.iostream isn't a good example of design <g>.They're value types (non-copyable for the most part, but stored directly instead of as pointers, with RAII), but they're often passed around as polymorphic references.I.e. they're a mess. You just confused the heck out of me.I use polymorphic references to value types occasionally. - C++ makes a clear distinction between a reference and the thing being referenced. Even if value types and polymorphism were mutually exclusive, this distinction would be useful. All types are consistently treated as value types, even those types that reference another object. I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'. I *like* having to write 'p->f();' instead of 'p.f();'. It keeps my code clearly and more explicit. - C++ does not have separate rules for value types and reference types. All types are implicitly value types; values of all types can be placed on the heap. This simplifies the language by having just one set of rules instead of separate rules for classes and structs. Again, this unification would be useful even if it was an error to declare a variable of a polymorphic type as a direct variable.That philosophy conflicts with using . for values and -> for references.The capability of being able to move value types is deliberately designed in. It's there for the obvious reason of being able to create a moving garbage collector, and for the more subtle reason of being able to optimize away many more cases of copy-construction and destruction.There are things that copy constructors can do that the post-blit operator can't do. Also, unless I am mistaken, D can move value types around in memory at will, which also invalidates designs that are useful in C++.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.
Jul 23 2009
On Thu, Jul 23, 2009 at 3:21 PM, Walter Bright<newshound1 digitalmars.com> wrote:Rainer Deyke wrote:I think the case he's talking about is just a sort of optimization to use stack allocation instead of heap alloc. void func() { DerivedFoo x; callMethodThatTakesAnyFoo(&x); } I.e. the kind of thing you'd use "scope Foo" for in D. Except that in the C++ case you could have DerivedFoo be part of another struct or class instead of being a local variable. --bb=A0 =A0They're value types (non-copyable for the most part, but stored directly instead of as pointers, with RAII), but they're often passed around as polymorphic references.I.e. they're a mess. You just confused the heck out of me.
Jul 23 2009
Walter Bright wrote:Rainer Deyke wrote:Composition instead of inheritance? Doesn't work if I need virtual functions.- Implementation inheritance of value types, even without actual polymorphism, is useful. See, for example, the curiously recurring template pattern (and all of its uses).You can do this with 'alias this'.I fully agree, but /this particular aspect/ of iostreams isn't an example of bad design either. How would you do this in D? Turning iostreams into reference types isn't the answer, especially if this means losing RAII. Non-polymorphics iostreams is also no-go. I suppose you could create a polymorphic reference-type wrapper around a pointer to the actual iostream struct, but that's a lot of extra work that isn't necessary in C++.- Polymorphic references to value types are often useful. D has references to value types (in the form of 'ref' parameters and pointers) but these are not polymorphic. As an example, I would name the standard C++ iostream.iostream isn't a good example of design <g>.I don't see what's confusing about this. Most iostreams are non-copyable, i.e. the following just plain doesn't compile: stream_type a; stream_type b = a; Iostreams are not reference types, at all. It's not possible for one iostream to (accidentally or intentionally) alias another iostream. There are not idiomatically allocated with 'new'. Therefore they avoid the problems of having reference types in the language. Long distance bugs with iostreams are highly unlikely. Iostreams are passed as references - real references, with the 'T&' syntax, equivalent to 'ref T' in D - because that's the only way to pass them around. The callee always knows they are receiving a reference, because the '&' is an explicit part of the function signature.They're value types (non-copyable for the most part, but stored directly instead of as pointers, with RAII), but they're often passed around as polymorphic references.I.e. they're a mess. You just confused the heck out of me.Are you deliberately trying to misunderstand me? In C++, for any type T, there is a type T* (and shared_ptr<T> and inclusive_ptr<T> and so on). T is a value type, always. T* is a pointer to a value of type T, but T* itself is still a value type. Given 'T* p;', 'p.x' accesses a member of 'p', while 'p->x' or '(*p).x' accesses a member of the value referenced by 'p'. Always, consistently, whether 'T' itself is a primitive type, a class, or even itself a pointer type.- C++ makes a clear distinction between a reference and the thing being referenced. Even if value types and polymorphism were mutually exclusive, this distinction would be useful. All types are consistently treated as value types, even those types that reference another object. I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'. I *like* having to write 'p->f();' instead of 'p.f();'. It keeps my code clearly and more explicit. - C++ does not have separate rules for value types and reference types. All types are implicitly value types; values of all types can be placed on the heap. This simplifies the language by having just one set of rules instead of separate rules for classes and structs. Again, this unification would be useful even if it was an error to declare a variable of a polymorphic type as a direct variable.That philosophy conflicts with using . for values and -> for references.The capability of being able to move value types is deliberately designed in. It's there for the obvious reason of being able to create a moving garbage collector, and for the more subtle reason of being able to optimize away many more cases of copy-construction and destruction.I know. Still, it invalidates valid C++ idioms. If there was some way to say "this struct cannot be moved", or even a hook function that is called before/after/during each move, then those idioms might still be valid. -- Rainer Deyke - rainerd eldwood.com
Jul 23 2009
On Thu, Jul 23, 2009 at 5:20 PM, Rainer Deyke<rainerd eldwood.com> wrote:Walter Bright wrote: I don't see what's confusing about this. Most iostreams are non-copyable, i.e. the following just plain doesn't compile: =A0stream_type a; =A0stream_type b =3D a; Iostreams are not reference types, at all. =A0It's not possible for one iostream to (accidentally or intentionally) alias another iostream. There are not idiomatically allocated with 'new'. =A0Therefore they avoid the problems of having reference types in the language.I don't get your meaning in that last sentence. What's the problem of having reference types in the language? C++ has reference types in the language -- T&. If you just mean it's not possible to forget to deallocate on scope exit, then you just need to use "scope" in D to get that effect. Or an explicit "scope(exit)" clause.Long distance bugs with iostreams are highly unlikely. Iostreams are passed as references - real references, with the 'T&' syntax, equivalent to 'ref T' in D - because that's the only way to pass them around. =A0The callee always knows they are receiving a reference, because the '&' is an explicit part of the function signature.Seems like scope handles most of this just fine. Except the case where you want to have an iostream as part of a larger class. But then that larger class is probably going to need deterministic destruction too, so wherever it's used it should probably be scope'ed also. --bb
Jul 23 2009
Rainer Deyke wrote:Walter Bright wrote:This is going in circles. You started from "implementation inheritance of value types, even without actual polymorphism". AndreiRainer Deyke wrote:Composition instead of inheritance? Doesn't work if I need virtual functions.- Implementation inheritance of value types, even without actual polymorphism, is useful. See, for example, the curiously recurring template pattern (and all of its uses).You can do this with 'alias this'.
Jul 24 2009
Andrei Alexandrescu wrote:Rainer Deyke wrote:Yes, but implementation inheritance may involve customization points. Virtual functions are one of of providing this customization. The curiously recurring template pattern provides another way. Either way, the class looks like a non-polymorphic value type from the outside. Simple composition does *not* work here, unless the inner component has a pointer to the outer aggregate. -- Rainer Deyke - rainerd eldwood.comComposition instead of inheritance? Doesn't work if I need virtual functions.This is going in circles. You started from "implementation inheritance of value types, even without actual polymorphism".
Jul 24 2009
Rainer Deyke wrote:Andrei Alexandrescu wrote:I'll try to briefly reply to this (I've been offline since yesterday's storm when a thunder fried the cable modem).Rainer Deyke wrote:In a way, that's a loaded question, since C++ classes don't stay polymorphic when passed around by value. Actual polymorphic value types that stay polymorphic when copied would be much more useful. However, even the limited polymorphic value types of C++ are useful.1. C++'s object model, complete with polymorphic value types,What designs make good use of polymorphic value types?Let's see: - Implementation inheritance of value types, even without actual polymorphism, is useful. See, for example, the curiously recurring template pattern (and all of its uses). And, yes, you can achieve similar results in D by using template mixins, but this is a specialized mechanism where C++ manages to do with the same generalized mechanism used for polymorphism and interface inheritance. I use inheritance of value types all the time.Well I use it sometimes too, but it's so fraught with peril that virtually all coding standards I've ever seen, all books and magazine articles on the topic, all pundits, say one thing: don't. Better use composition.- Polymorphic references to value types are often useful. D has references to value types (in the form of 'ref' parameters and pointers) but these are not polymorphic. As an example, I would name the standard C++ iostream. They're value types (non-copyable for the most part, but stored directly instead of as pointers, with RAII), but they're often passed around as polymorphic references. I use polymorphic references to value types occasionally.I don't know what polymorphic references to value types mean, and I don't think iostreams are representative for the matter, or a good design in general.- C++ makes a clear distinction between a reference and the thing being referenced. Even if value types and polymorphism were mutually exclusive, this distinction would be useful. All types are consistently treated as value types, even those types that reference another object.This is incorrect. C++ references are not value types. The design of references in C++ is particularly poor.I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'. I *like* having to write 'p->f();' instead of 'p.f();'. It keeps my code clearly and more explicit.I understand, but that's a judgment call (e.g. explicit calls instead of operator overloading). Other people prefer the opposite.- C++ does not have separate rules for value types and reference types. All types are implicitly value types; values of all types can be placed on the heap. This simplifies the language by having just one set of rules instead of separate rules for classes and structs. Again, this unification would be useful even if it was an error to declare a variable of a polymorphic type as a direct variable.Again, C++ has references which kind of introduce separate and very different rules.Yes, mostly wrong things. I think it would be a huge loss if D copied C++'s model.There are things that copy constructors can do that the post-blit operator can't do.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.Also, unless I am mistaken, D can move value types around in memory at will, which also invalidates designs that are useful in C++.C++ copy+destroy sequence has been an absolute pest for years. Rvalue references fix that by adding another layer of complexity. I'm very happy D didn't inherit that. Andrei
Jul 24 2009
Andrei Alexandrescu wrote:Well I use it sometimes too, but it's so fraught with peril that virtually all coding standards I've ever seen, all books and magazine articles on the topic, all pundits, say one thing: don't. Better use composition.My take on composition vs inheritance is very simple: always use composition, unless you absolutely need inheritance. Sometimes I absolutely need inheritance, and D isn't giving it to me. I don't care about your coding standards. I know how to use C++. I have my own rules about how to use it safely and effectively, rules that I have spent a lifetime refining. I still make mistakes, but almost all of my bugs are of the simple stupid kind that can be made in all languages. I don't need or want D to protect me from the pitfalls of C++ if this means significantly reducing the expressive power of the language. I don't want a safe language for little kids, I want a real language for adults. (And, truly, D is better in this regard than many of its competitors. Perhaps the awesome power of string mixins will be enough to offset its missing features. I will definitely give D2 a try when it is finished.) -- Rainer Deyke - rainerd eldwood.com
Jul 24 2009
Rainer Deyke wrote:Andrei Alexandrescu wrote:Whether we like it or not, programming has a large social component. AndreiWell I use it sometimes too, but it's so fraught with peril that virtually all coding standards I've ever seen, all books and magazine articles on the topic, all pundits, say one thing: don't. Better use composition.My take on composition vs inheritance is very simple: always use composition, unless you absolutely need inheritance. Sometimes I absolutely need inheritance, and D isn't giving it to me. I don't care about your coding standards. I know how to use C++. I have my own rules about how to use it safely and effectively, rules that I have spent a lifetime refining.
Jul 24 2009
Rainer Deyke wrote:I don't care about your coding standards. I know how to use C++. I have my own rules about how to use it safely and effectively, rules that I have spent a lifetime refining.I've been writing software for 35 years. I'm still learning new ways of doing things and discarding old ones.(And, truly, D is better in this regard than many of its competitors. Perhaps the awesome power of string mixins will be enough to offset its missing features.Probably the most frustrating thing to me when coding C++ is the lack of nested functions. The workaround is awfully ugly.
Jul 24 2009
Walter Bright wrote:Rainer Deyke wrote:But goto will never die :o). AndreiI don't care about your coding standards. I know how to use C++. I have my own rules about how to use it safely and effectively, rules that I have spent a lifetime refining.I've been writing software for 35 years. I'm still learning new ways of doing things and discarding old ones.
Jul 24 2009
Fri, 24 Jul 2009 16:58:50 -0500, Andrei Alexandrescu wrote:This means that structs cannot hold on external resources, ever: struct RAII {...} var a = RAII("foo"); var b = RAII("bar"); a = b; // you just leaked a and corrupted bYes, mostly wrong things. I think it would be a huge loss if D copied C++'s model.There are things that copy constructors can do that the post-blit operator can't do.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.
Jul 26 2009
Sergey Gromov wrote:Fri, 24 Jul 2009 16:58:50 -0500, Andrei Alexandrescu wrote:You may be making a confusion between assignment and copy construction. AndreiThis means that structs cannot hold on external resources, ever: struct RAII {...} var a = RAII("foo"); var b = RAII("bar"); a = b; // you just leaked a and corrupted bYes, mostly wrong things. I think it would be a huge loss if D copied C++'s model.There are things that copy constructors can do that the post-blit operator can't do.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.
Jul 26 2009
Sun, 26 Jul 2009 21:23:35 -0500, Andrei Alexandrescu wrote:Sergey Gromov wrote:Sure I'm confusing them, silly me. The only thing copy-construction is useful for is implementing move semantics, think std::auto_ptr. Seems like everything else can be done in post-blit. The inability to overload opAssign(typeof(this)) is a blocker for robust RAII though.Fri, 24 Jul 2009 16:58:50 -0500, Andrei Alexandrescu wrote:You may be making a confusion between assignment and copy construction.This means that structs cannot hold on external resources, ever: struct RAII {...} var a = RAII("foo"); var b = RAII("bar"); a = b; // you just leaked a and corrupted bYes, mostly wrong things. I think it would be a huge loss if D copied C++'s model.There are things that copy constructors can do that the post-blit operator can't do.deterministic destructors, arbitrary copy constructors, and optional lack of default constructor.Struct have that except for default constructor. In D, currently default constructors cannot execute code. This is a limitation that we might need to address, although it has some advantages.
Jul 27 2009
Sergey Gromov wrote:The only thing copy-construction is useful for is implementing move semantics, think std::auto_ptr. Seems like everything else can be done in post-blit.The "linked list" implementation of smart pointers also requires a copy constructor. It's (arguably) not a very good design, but it is a valid design.The inability to overload opAssign(typeof(this)) is a blocker for robust RAII though.Yes. -- Rainer Deyke - rainerd eldwood.com
Jul 27 2009
Rainer Deyke wrote:1. C++'s object model, complete with polymorphic value types, deterministic destructors, arbitrary copy constructors, and optional lack of default constructor. D's structs come close, but I think the class/struct split hurts D more than it helps. And, yes, C++ has a lot of room for improvement here.I'm with Andrei in saying that polymorphic value types are a very bad idea. I've never seen a use case for them that wasn't a mistake.
Jul 23 2009
"Rainer Deyke" <rainerd eldwood.com> wrote in message news:h49153$2pbq$1 digitalmars.com...Walter Bright wrote:D is certainly a bit messy compared to many languages, but I have a very difficult time imagining how it could be considered messy in comparison to C++. C++ has decades of accumulated cruft from trying to cram in usable-but-clumbsy new features around piles of backwards-compatible anachronisms. The mess in D barely begins until a level that's far beyond where C++ takes you before getting messy. And this cannot be a result of me having become more accustomed to D than C++ - I've considered C++ the messiest non-dead language I know of since before I came across D, and even since the last time I was using C++ as my primary language.My experience with C++ people sticking with it is they are so used to the problems they no longer see them. To me it's like the mess in one's house. One doesn't notice it until going on a vacation (i.e. learning a another language), having one's hotel room cleaned every day, then coming home and suddenly seeing how untidy it is <g>.I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of new features thrown in without rhyme or reason". D is many things, but a simple and elegant language it is not. (This is not a major problem to me, really. I can live with messy languages. I can live with C++. But to think that D is a massive improvement in this area requires a special sort of perspective.)
Jul 23 2009
== Quote from Rainer Deyke (rainerd eldwood.com)'s articleWalter Bright wrote:My experience with D people sticking with it is ... Not knowing that it can be done easier in another language is a bliss.My experience with C++ people sticking with it is they are so used to the problems they no longer see them. To me it's like the mess in one'sDelphi ------ D = (Java) + C++ Seems to me D only needs to learn from Delphi. Delphi is the first RAD language designed to easily interact with the IDE. Java wasn't, see the tonnes (non-metric unit of amount of code) of code that the IDE produces. I believe now Java has all the necessary features, it is just that swing just isn't the VCL. They could easily add a D style "property/method" syntax but they just won't since they want to stick to swing, which I think they need to drop. Two important features from Delphi 1) properties: Easily distinguishable from normal methods in the reflection, just enough to know what to display in the object inspector and not to rely on the name of the method. Object Inspector is a window displaying two columns, for normal properties and events. Property Name1, Property Value1 Property Name2, Property Value2 What is the purpose of properties? "The purpose of properties is to facilitate the interaction with the IDE" 2) published: Delphi has private, protected, public, published. 2.1) All published methods and properties are shown in the reflection, RTTI (sort of a selective reflection {$M+}). 2.2) Everything passed to a published methods or property is serializable (in Delphi terminology derives from TPersistent or basic type like integer and stuff) 2.3) You can't have published fields only published properties, and methods (Also note D people want properties to look like fields somehow) (Delphi starts their fields with F in front FNumber). Delphi might not have full reflection but the minimum it has is very powerful. The VCL (state of the art library) is well designed, the components are AWARE of either running in the client application or running from within the IDE, hence can change their behaviour, to adapt to the changes, minimizing what the actual IDE has to do. Part of its design is a virtual constructor. C++ + Another Language layered on top of C++ -------------------------------------------- 1) Combining C++ with another language is "fairly" easy. the introduction of the garbage collector, this becomes difficult. (The "pied" guy might disagree) I think for D to be successful it will not only have to be an enhanced C++house. One doesn't notice it until going on a vacation (i.e. learning a another language), having one's hotel room cleaned every day, then coming home and suddenly seeing how untidy it is <g>.I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of
Jul 23 2009
sclytrack wrote:== Quote from Rainer Deyke (rainerd eldwood.com)'s articleUnfortunately the designers of D doesn't care at all about IDE support for their language, even though in any "why don't you use D" discussion it is mentioned.Walter Bright wrote:My experience with D people sticking with it is ... Not knowing that it can be done easier in another language is a bliss.My experience with C++ people sticking with it is they are so used to the problems they no longer see them. To me it's like the mess in one'sDelphi ------ D = (Java) + C++ Seems to me D only needs to learn from Delphi. Delphi is the first RAD language designed to easily interact with the IDE. Java wasn't, see the tonnes (non-metric unit of amount of code) of code that the IDE produces. I believe now Java has all the necessary features, it is just that swing just isn't the VCL. They could easily add a D style "property/method" syntax but they just won't since they want to stick to swing, which I think they need to drop. Two important features from Delphi 1) properties: Easily distinguishable from normal methods in the reflection, just enough to know what to display in the object inspector and not to rely on the name of the method. Object Inspector is a window displaying two columns, for normal properties and events. Property Name1, Property Value1 Property Name2, Property Value2 What is the purpose of properties? "The purpose of properties is to facilitate the interaction with the IDE"house. One doesn't notice it until going on a vacation (i.e. learning a another language), having one's hotel room cleaned every day, then coming home and suddenly seeing how untidy it is <g>.I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of
Jul 23 2009
Ary Borenszweig wrote:Unfortunately the designers of D doesn't care at all about IDE support for their language, even though in any "why don't you use D" discussion it is mentioned.The problem is not not caring. For one, I'd love a D IDE as much as the next guy, but I don't have the resources to put into writing one. IDEs come with language acceptance and are seldom written by the creator of the language. By the way, we must be doing something right. As of ten days ago there were 30,800 page views for The Case for D, and I just noticed that in the past week the presale rate for The D Programming Language has doubled. Andrei
Jul 23 2009
Andrei Alexandrescu wrote:Ary Borenszweig wrote:I'm not talking about writing an IDE. I'm talking about when thinking of a feature, think how this could be supported in an IDE. When you are debugging and you watch some varaible, the debugger automatically allows you to expand a node and see the varaible's properties. You can't do that with D because any function that has zero parameters could be a property, even though some functions aren't properties.Unfortunately the designers of D doesn't care at all about IDE support for their language, even though in any "why don't you use D" discussion it is mentioned.The problem is not not caring. For one, I'd love a D IDE as much as the next guy, but I don't have the resources to put into writing one. IDEs come with language acceptance and are seldom written by the creator of the language.By the way, we must be doing something right. As of ten days ago there were 30,800 page views for The Case for D, and I just noticed that in the past week the presale rate for The D Programming Language has doubled.Great! :-)
Jul 23 2009
Ary Borenszweig Wrote:Andrei Alexandrescu wrote:While working on QtD I have also come up with the conclusion that D needs proper properties. Qt itself greatly relies on properties and it makes a lot of cool things possible. Of course C++ doesn't support them, it is done via Qt metatype system. When D goes popular, IDEs will severely lack this functionality from the language.Ary Borenszweig wrote:I'm not talking about writing an IDE. I'm talking about when thinking of a feature, think how this could be supported in an IDE. When you are debugging and you watch some varaible, the debugger automatically allows you to expand a node and see the varaible's properties. You can't do that with D because any function that has zero parameters could be a property, even though some functions aren't properties.Unfortunately the designers of D doesn't care at all about IDE support for their language, even though in any "why don't you use D" discussion it is mentioned.The problem is not not caring. For one, I'd love a D IDE as much as the next guy, but I don't have the resources to put into writing one. IDEs come with language acceptance and are seldom written by the creator of the language.
Jul 23 2009
Eldar Insafutdinov wrote:Ary Borenszweig Wrote:...There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?When you are debugging and you watch some varaible, the debugger automatically allows you to expand a node and see the varaible's properties. You can't do that with D because any function that has zero parameters could be a property, even though some functions aren't properties.While working on QtD I have also come up with the conclusion that D needs proper properties. Qt itself greatly relies on properties and it makes a lot of cool things possible. Of course C++ doesn't support them, it is done via Qt metatype system. When D goes popular, IDEs will severely lack this functionality from the language.
Jul 23 2009
Lutger wrote:There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?Property DIPs have been offered in the newsgroup in the past, only before they were called DIPs. I also offered a possible design: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81759 Feel free to modify and/or DIPify it. -- Michiel Helvensteijn
Jul 23 2009
On Thu, Jul 23, 2009 at 1:53 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:Lutger wrote:""" I've always thought properties should work somewhat like this: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } } """ I'm curious. Is it just a coincidence that how you've "always In any event I think a problem with this is that for D's simple grammar to remain simple and context free, get and set would both have to be made keywords in the language. Can a compiler guru confirm that? Not a big issue, but introducing 3 keywords for this one feature will be a tough sell. Perhaps just property int length { () { return this.len; } (newLen) { this.len = newLen; } } would be enough. Maybe I'm wrong about get/set being an issue, though. --bbThere have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?Property DIPs have been offered in the newsgroup in the past, only before they were called DIPs. I also offered a possible design: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81759 Feel free to modify and/or DIPify it.
Jul 23 2009
Bill Baxter wrote:Not a big issue, but introducing 3 keywords for this one feature will be a tough sell. --bbAt least it's not 5 like vb.net, but that beast already has 150 keywords so I guess a couple more doesn't matter that much :)
Jul 23 2009
On Thu, Jul 23, 2009 at 2:19 PM, Lutger<lutger.blijdestijn gmail.com> wrote:Bill Baxter wrote:I do think it would be justifiable to add one more keyword for real properties, just not three. If the get/set could somehow be context keywords then that would be nice. I know these sorts of context keywords are ok in D's grammar version(Foo) and foreach(reverse) was bandied about as being acceptable since they have a clear contextual scope, just not sure if get/set inside a property block would qualify. --bbNot a big issue, but introducing 3 keywords for this one feature will be a tough sell. --bbAt least it's not 5 like vb.net, but that beast already has 150 keywords so I guess a couple more doesn't matter that much :)
Jul 23 2009
On Thu, 23 Jul 2009 17:13:13 -0400, Bill Baxter <wbaxter gmail.com> wrote:In any event I think a problem with this is that for D's simple grammar to remain simple and context free, get and set would both have to be made keywords in the language. Can a compiler guru confirm that? Not a big issue, but introducing 3 keywords for this one feature will be a tough sell. Perhaps just property int length { () { return this.len; } (newLen) { this.len = newLen; } } would be enough. Maybe I'm wrong about get/set being an issue, though.I think you might be wrong. operator functions like opAdd are not keywords, but are treated specially by the compiler. The compiler would probably just change the get and set functions into mangled symbols that would never be generated from a normal function, so no keywords would be required. -Steve
Jul 23 2009
On Thu, Jul 23, 2009 at 2:25 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:On Thu, 23 Jul 2009 17:13:13 -0400, Bill Baxter <wbaxter gmail.com> wrote=:.In any event I think a problem with this is that for D's simple grammar to remain simple and context free, get and set would both have to be made keywords in the language. =A0Can a compiler guru confirm that? =A0Not a big issue, but introducing 3 keywords for this one feature will be a tough sell. =A0 Perhaps just property int length { =A0 =A0() { return this.len; } =A0 =A0(newLen) { this.len =3D newLen; } } would be enough. =A0Maybe I'm wrong about get/set being an issue, though=I think you might be wrong. =A0operator functions like opAdd are not keyw=ords,but are treated specially by the compiler. =A0The compiler would probably=justchange the get and set functions into mangled symbols that would never be generated from a normal function, so no keywords would be required.That makes sense. Maybe Walter would like to take this opportunity to plug his upcoming compiler building seminar for us compiler ignoramuses. :-) --bb
Jul 23 2009
Bill Baxter wrote:""" I've always thought properties should work somewhat like this: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } } """ I'm curious. Is it just a coincidence that how you've "alwayslot, and this is what I came up with. From that newsgroup thread, it seemsIn any event I think a problem with this is that for D's simple grammar to remain simple and context free, get and set would both have to be made keywords in the language.I don't think so. They can just be identifiers with special meaning. If you look a bit further down the thread, I suggest adding the 'auto' keyword where the missing types are now. Perhaps that helps. In fact, in the design of my own language, those names have special meaning for all types: get(x) (or x.get()) returns x itself. set(x, v) (or x.get(v)) assigns v to x. If you specify them in a property, you're just overriding their meaning for the underlying type of the property, just like you can override other member-functions. Another upside is that you can always count on these functions existing for every type and you can pass them around as functions/delegates. -- Michiel Helvensteijn
Jul 23 2009
Michiel Helvensteijn wrote:set(x, v) (or x.get(v)) assigns v to x.Small correction: x.set(v) -- Michiel Helvensteijn
Jul 23 2009
Michiel Helvensteijn Wrote:Lutger wrote:from your post: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?Property DIPs have been offered in the newsgroup in the past, only before they were called DIPs. I also offered a possible design: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81759 Feel free to modify and/or DIPify it. -- Michiel Helvensteijn
Jul 23 2009
Eldar Insafutdinov wrote:from your post: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interface of a type into the property without code duplication. -- Michiel Helvensteijn
Jul 23 2009
On Thu, Jul 23, 2009 at 5:56 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:Eldar Insafutdinov wrote:edfrom your post: property int length { =A0 =A0 get() { return this.len; } =A0 =A0 set(newLen) { this.len =3D newLen; } =A0 =A0 void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimit=and unrestricted access to that variable with only one call, and you migh=tas well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interface o=f atype into the property without code duplication.You're suggesting adding something like 25 operator overloads to every property. Can you say "code bloat"? Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op=3D value; Simply becomes: obj.prop.set(obj.prop.get op value);
Jul 23 2009
Jarrett Billingsley wrote:You're suggesting adding something like 25 operator overloads to every property. Can you say "code bloat"?It may not be necessary in simple situations where the compiler can figure out that it may use a more direct way. But I believe it is the right way to go if you want more speed out of your properties, yes.Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op= value; Simply becomes: obj.prop.set(obj.prop.get op value);There are several issues with that suggestion: * It works only if (a op= b) always behaves the same as (a = a op b). * It would only work for op= operators. It can't do anything for arbitrary mutator methods on the type of the property. * In most situations, it will still be as slow as my suggested 'slow way', without any extra operator overloads! I will repeat my 'slow' transformation here again: obj.prop op= value; // auto temp = obj.prop.get(); // temp op= value; // obj.prop.set(value); At least with that you don't have those first two issues. -- Michiel Helvensteijn
Jul 24 2009
Jarrett Billingsley wrote:On Thu, Jul 23, 2009 at 5:56 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:I think this would be inefficient in many cases. AndreiEldar Insafutdinov wrote:You're suggesting adding something like 25 operator overloads to every property. Can you say "code bloat"? Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op= value; Simply becomes: obj.prop.set(obj.prop.get op value);from your post: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interface of a type into the property without code duplication.
Jul 24 2009
On Fri, Jul 24, 2009 at 5:19 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Um, what do you have to write now? "obj.prop = obj.prop op value". All I'm suggesting is that the compiler automatically transform the expression for you. Also, what someone else suggested - that it become "auto temp = obj.prop get; temp op= value; obj.prop.set(temp)" - is technically more correct, in terms of operator overloading (i.e. if the property returns a BigInt, or something).obj.prop op= value; Simply becomes: obj.prop.set(obj.prop.get op value);I think this would be inefficient in many cases.
Jul 24 2009
On Fri, Jul 24, 2009 at 2:19 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Jarrett Billingsley wrote:stOn Thu, Jul 23, 2009 at 5:56 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:Eldar Insafutdinov wrote:from your post: property int length { =A0 =A0get() { return this.len; } =A0 =A0set(newLen) { this.len =3D newLen; } =A0 =A0void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the be=nsperformance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actio=That is true but I also think: * probably that is the best that can be achieved automatically. * if better can be achieved automatically then the compiler can just do that under the hood. No user code needs to change. * set(get op value) probably won't be inefficient in some cases. * having a op=3D b work automatically in an inefficient way is better than forcing the users of the code to make the same ineffecient transformation in their code manually (which is the status quo of property syntax in D). So I think how to make a op=3D b whizzy fast can be decided later. And for now set(get op value) is good enough. --bbI think this would be inefficient in many cases.to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interface of a type into the property without code duplication.You're suggesting adding something like 25 operator overloads to every property. =A0Can you say "code bloat"? Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op=3D value; Simply becomes: obj.prop.set(obj.prop.get op value);
Jul 24 2009
Bill Baxter wrote:On Fri, Jul 24, 2009 at 2:19 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Ok, I got convinced. AndreiJarrett Billingsley wrote:That is true but I also think: * probably that is the best that can be achieved automatically. * if better can be achieved automatically then the compiler can just do that under the hood. No user code needs to change. * set(get op value) probably won't be inefficient in some cases. * having a op= b work automatically in an inefficient way is better than forcing the users of the code to make the same ineffecient transformation in their code manually (which is the status quo of property syntax in D). So I think how to make a op= b whizzy fast can be decided later. And for now set(get op value) is good enough.On Thu, Jul 23, 2009 at 5:56 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:I think this would be inefficient in many cases.Eldar Insafutdinov wrote:You're suggesting adding something like 25 operator overloads to every property. Can you say "code bloat"? Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op= value; Simply becomes: obj.prop.set(obj.prop.get op value);from your post: property int length { get() { return this.len; } set(newLen) { this.len = newLen; } void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interface of a type into the property without code duplication.
Jul 24 2009
On Fri, Jul 24, 2009 at 6:44 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Bill Baxter wrote:hOn Fri, Jul 24, 2009 at 2:19 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Jarrett Billingsley wrote:On Thu, Jul 23, 2009 at 5:56 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:Eldar Insafutdinov wrote:from your post: property int length { =A0 get() { return this.len; } =A0 set(newLen) { this.len =3D newLen; } =A0 void opIncrement() { this.len++; } } I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, whic=aeliminates the issue.If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all. If your property is derived -- that is, if it doesn't directly mirror=cevariable --, there is no reference to return. Besides, in D, you can probably use mixins to copy the entire interfa=dThat is true but I also think: * probably that is the best that can be achieved automatically. * if better can be achieved automatically then the compiler can just do that under the hood. =A0No user code needs to change. * set(get op value) probably won't be inefficient in some cases. * having a op=3D b work automatically in an inefficient way is better than forcing the users of the code to make the same ineffecient transformation in their code manually (which is the status quo of property syntax in D). So I think how to make a op=3D b whizzy fast can be decided later. =A0An=I think this would be inefficient in many cases.of a type into the property without code duplication.You're suggesting adding something like 25 operator overloads to every property. =A0Can you say "code bloat"? Why not just use the following solution, which has been proposed God-knows-how-many-times and already has precedence in other languages obj.prop op=3D value; Simply becomes: obj.prop.set(obj.prop.get op value);Have you also seen Michiel's suggestion? obj.prop op=3D value; // auto temp =3D obj.prop.get(); // temp op=3D value; // obj.prop.set(value); I think this is probably somewhat more correct, in the face of operator overloading on typeof(temp). That is, if obj.prop is a struct that overloads opAddAssign, you'd want "obj.prop +=3D 5" to really call obj.prop's opAddAssign, rather than its opAdd.for now set(get op value) is good enough.Ok, I got convinced.
Jul 24 2009
"Lutger" <lutger.blijdestijn gmail.com> wrote in message news:h4agu7$2cme$1 digitalmars.com...There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4 I'm making a post for this over on D.announce...
Jul 23 2009
"Nick Sabalausky" <a a.a> wrote in message news:h4bdmq$115p$1 digitalmars.com..."Lutger" <lutger.blijdestijn gmail.com> wrote in message news:h4agu7$2cme$1 digitalmars.com...Erm... I mean right here on digitalmars.D...There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4 I'm making a post for this over on D.announce...
Jul 23 2009
It is said that "Character decided fate" . W.B's character decided the fate of watcom C, and now the fate of D. Just as it is said in the homepage, D is the code for nerds ,not the code for thinkers as LISP, nor the code for creators as C,nor the code for users like perl. Sorry to say so.
Jul 24 2009
goooooo wrote:It is said that "Character decided fate" . W.B's character decided the fate of watcom C, and now the fate of D. Just as it is said in the homepage, D is the code for nerds ,not the code for thinkers as LISP, nor the code for creators as C,nor the code for users like perl. Sorry to say so.I am not and never was associated with Watcom C in any way, other than as a competitor. I have an old copy of it in the basement <g>. The compiler products I've worked on: http://www.walterbright.com
Jul 24 2009
Walter Bright wrote:goooooo wrote:http://www.walterbright.com/garage/index.html YEAAAH!!It is said that "Character decided fate" . W.B's character decided the fate of watcom C, and now the fate of D. Just as it is said in the homepage, D is the code for nerds ,not the code for thinkers as LISP, nor the code for creators as C,nor the code for users like perl. Sorry to say so.I am not and never was associated with Watcom C in any way, other than as a competitor. I have an old copy of it in the basement <g>. The compiler products I've worked on: http://www.walterbright.com
Jul 24 2009
On Fri, Jul 24, 2009 at 2:58 PM, Ary Borenszweig<ary esperanto.org.ar> wrote:Walter Bright wrote:What! Descent! You don't SELL Descent. You treasure it for years and years, owing your entire interest in programming to it.goooooo wrote:http://www.walterbright.com/garage/index.html YEAAAH!!It is said that "Character decided fate" . W.B's character decided the fate of watcom C, and now the fate of D. Just as it is said in the homepage, D is the code for nerds ,not the code for thinkers as LISP, nor the code for creators as C,nor the code for users like perl. Sorry to say so.I am not and never was associated with Watcom C in any way, other than as a competitor. I have an old copy of it in the basement <g>. The compiler products I've worked on: http://www.walterbright.com
Jul 24 2009
Jarrett Billingsley wrote:What! Descent! You don't SELL Descent. You treasure it for years and years, owing your entire interest in programming to it.Bah, I have a basement full of such treasures. I finally took to the dump my Diablo 630 daisywheel printer. It was in mint condition, with manual, extra ribbons, cables, etc. I bought it for $1,000 back in 1982. It was built like a tank (and sounded like a machine gun when in action!). It produced beautiful printed pages. I couldn't find anyone who wanted it, not even old computer museums.
Jul 24 2009
Lutger wrote:Eldar Insafutdinov wrote:Yes please. AndreiAry Borenszweig Wrote:...There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?When you are debugging and you watch some varaible, the debugger automatically allows you to expand a node and see the varaible's properties. You can't do that with D because any function that has zero parameters could be a property, even though some functions aren't properties.While working on QtD I have also come up with the conclusion that D needs proper properties. Qt itself greatly relies on properties and it makes a lot of cool things possible. Of course C++ doesn't support them, it is done via Qt metatype system. When D goes popular, IDEs will severely lack this functionality from the language.
Jul 24 2009
Andrei Alexandrescu wrote:By the way, we must be doing something right. As of ten days ago there were 30,800 page views for The Case for D, and I just noticed that in the past week the presale rate for The D Programming Language has doubled.Must be those classicempire affiliate links!!!
Jul 23 2009
sclytrack wrote:I think for D to be successful it will not only have to be an enhanced C++I think D should also visibly obviate some use of Python or Perl for prototyping. Thank you for your insightful post, the points on reflection and Delphi were excellent. Andrei
Jul 23 2009
Wed, 22 Jul 2009 23:10:53 +0200, Michiel Helvensteijn wrote:* Tuples (no dedicated syntax, no parallel assignment, no non-flattening tuples without workarounds, no returning tuples)I'm planning to write a DIP on better tuple support. Here is a brief overview of my ideas. I think I'll blog a bit more before filing an actual DIP. http://snakecoder.wordpress.com/2009/07/28/language-support-for-tuples-in-d
Jul 27 2009
Walter Bright wrote:http://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_program ing_language_looks/I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs? Andrei
Jul 22 2009
On Wed, Jul 22, 2009 at 06:27:50PM -0500, Andrei Alexandrescu wrote:I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs?I think the installation difficulties are the result of poor instructions (especially on Linux), not anything technical. The website talks about copying files places. This isn't necessary: the way it works is to unzip it and go. It doesn't get any simpler, but the instructions don't really reflect that. I actually got a private email from a new D user over the weekend talking about how hard it is on Linux. I replied with my method: 1) Make helper scripts in /usr/bin with this content: $ cat /usr/bin/dmd /lib/ld-linux.so.2 /home/me/d/dmd2/linux/bin/dmd $* 2) Download the DMD zip from the changelog page into the path your script references (/home/me/d in my example). 3) Unzip it. 4) Have fun coding! (Note you can do something very similar on Windows with a helper .bat file.) That's how easy installing DMD is, but this guy, and many others, don't see it that way. I blame this page: http://www.digitalmars.com/d/2.0/dmd-linux.html#installation The Windows page isn't much better. That is much harder and less clear than it needs to be. I really think fixing those pages to have simpler, clearer instructions will make the requests for installers and packages go away.Andrei-- Adam D. Ruppe http://arsdnet.net
Jul 22 2009
Adam D. Ruppe wrote:That's how easy installing DMD is, but this guy, and many others, don't see it that way. I blame this page: http://www.digitalmars.com/d/2.0/dmd-linux.html#installation The Windows page isn't much better.Please post patches to bugzilla!
Jul 22 2009
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:mailman.131.1248306024.14071.digitalmars-d puremagic.com...That's how easy installing DMD is, but this guy, and many others, don't see it that way. I blame this page: http://www.digitalmars.com/d/2.0/dmd-linux.html#installationReally? That surprises me. I consider myself relatively green when it comes to Linux, and I've never once tried to use/install DMD on Linux (yet), or looked at that page before, but for Linux that looks pretty darn easy. Not apt-get easy of course, but even I've dealt with far worse than this. Not that it couldn't or shouldn't be improved, of course, but if someone is complaining that it's *dmd* that's too hard to install on Linux, then it sounds like they're in for a rather rough ride period ;)
Jul 23 2009
Nick Sabalausky wrote:Not apt-get easy of course,Linux Gentoo does have DMD in portage, by the way. apt-get easy. Or, to be more precise, emerge easy. -- Michiel Helvensteijn
Jul 23 2009
Michiel Helvensteijn Wrote:Nick Sabalausky wrote:Available versions: (~)1.016!m!s (~)2.008-r1!m!s You can use this overlay for the latest versions: http://www.assembla.com/wiki/show/d-overlay We usually update it in one day to one week from dmd release.Not apt-get easy of course,Linux Gentoo does have DMD in portage, by the way. apt-get easy. Or, to be more precise, emerge easy.
Jul 23 2009
On 2009-07-22 19:27:50 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Walter Bright wrote:Ihttp://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_programming_language_looks/My plan currently is to improve D for Xcode, make it work with DMD, create one or two project templates for D to display when you create a new project from Xcode, patch Apple's version of GDB to have better demangling support, and create an nice installer for all of this, ideally bundled with DMD 1 and 2 (if Walter permits). That should fix the install and toolchain problem on Mac OS X in a nice way. I plan to have this done by mid-August. -- Michel Fortin michel.fortin michelf.com http://michelf.com/noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs?
Jul 22 2009
On Wed, 22 Jul 2009 18:27:50 -0500, Andrei Alexandrescu wrote:Walter Bright wrote:ask_proggit_the_d_programming_language_looks/http://www.reddit.com/r/programming/comments/93jh5/I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs? AndreiI'm intending a rework of: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/InstallingDCompiler but haven't got around to it and can only cover Linux and Windows. The end result will be at: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/StartingWithD/Compiler/ DMD
Jul 22 2009
Jesse Phillips wrote:On Wed, 22 Jul 2009 18:27:50 -0500, Andrei Alexandrescu wrote:Thanks, we need more of that stuff. I think this is a common experience (pasted from the reddit discussion): ========== i couldn't manage to get the command line toolchain up and running in linux either. yes, part of it was me being lazy, but there really is no good documentation saying "this is where your D installation needs to go, these are the environment variables you need, this is how to write a makefile or equivalent, this is the filesystem layout the build tool expects, this is how to use a c library, etc". ========== A while ago Walter put a good amount of work into accelerating code generation by avoiding writing object files to disk. He mentioned that that's a nice feature that old and new users will notice. I agree with that, but I also think installation has a huge importance. Having streamlined code generation but a crappy installer is like showing up at a first date pocketing a condom, but wearing an MSDN conference T-shirt. AndreiWalter Bright wrote:ask_proggit_the_d_programming_language_looks/http://www.reddit.com/r/programming/comments/93jh5/I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs? AndreiI'm intending a rework of: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/InstallingDCompiler but haven't got around to it and can only cover Linux and Windows. The end result will be at: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/StartingWithD/Compiler/ DMD
Jul 22 2009
On Wed, 22 Jul 2009 22:19:29 -0500, Andrei Alexandrescu wrote:Jesse Phillips wrote:Compiler/On Wed, 22 Jul 2009 18:27:50 -0500, Andrei Alexandrescu wrote:Walter Bright wrote:ask_proggit_the_d_programming_language_looks/http://www.reddit.com/r/programming/comments/93jh5/I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs? AndreiI'm intending a rework of: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/InstallingDCompiler but haven't got around to it and can only cover Linux and Windows. The end result will be at: http://www.prowiki.org/wiki4d/wiki.cgi?D__Tutorial/StartingWithD/Oh, I know, I posted this response: http://www.reddit.com/r/programming/comments/93jh5/ ask_proggit_the_d_programming_language_looks/c0bbbs5 As for the needing more of it, we actually have too much. http://www.prowiki.org/wiki4d/wiki.cgi?EvaluationGuide http://www.prowiki.org/wiki4d/wiki.cgi?HowToGentoo http://www.prowiki.org/wiki4d/wiki.cgi?HowToUbuntu The trend seems to be, make your own, reference the old, and have everything outdated and complicated. There is a lot of good information, but it has to be presented properly with a concentrated effort (Kind of like the community being stretched across D1/Tango/D2).DMDThanks, we need more of that stuff. I think this is a common experience (pasted from the reddit discussion): ========== i couldn't manage to get the command line toolchain up and running in linux either. yes, part of it was me being lazy, but there really is no good documentation saying "this is where your D installation needs to go, these are the environment variables you need, this is how to write a makefile or equivalent, this is the filesystem layout the build tool expects, this is how to use a c library, etc". ========== A while ago Walter put a good amount of work into accelerating code generation by avoiding writing object files to disk. He mentioned that that's a nice feature that old and new users will notice. I agree with that, but I also think installation has a huge importance. Having streamlined code generation but a crappy installer is like showing up at a first date pocketing a condom, but wearing an MSDN conference T-shirt. Andrei
Jul 22 2009
On 7/23/09 1:27 AM, Andrei Alexandrescu wrote:Walter Bright wrote:Yes: http://www.dsource.org/projects/dmd-installer I'm still waiting for Walter to add the osx installer to the dmd download page.http://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_programming_language_looks/I noticed some people complain about installation difficulties, is there progress on the community project for writing installer for the three major OSs? Andrei
Jul 23 2009
On 2009-07-23 05:37:24 -0400, Jacob Carlborg <doob me.com> said:Yes: http://www.dsource.org/projects/dmd-installer I'm still waiting for Walter to add the osx installer to the dmd download page.Speaking of that OS X DMD installer, are you sure installing it at /usr/share/dmd/ is a good idea? Normally /usr/share is reserved for architecture-independent data[1], not executable files. What about /usr/local/dmd with symlinks in /usr/local/bin for executables /usr/local/lib for phobos and druntime and /usr/local/man for man pages. Or perhaps install /Library/D/{dmd,dmd2} so the files are more user accessible and easy to change if you got the zip archive (/usr is a hidden dir on Mac OS X). If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts? [1]: http://www.pathname.com/fhs/2.2/fhs-4.11.html -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jul 23 2009
Michel Fortin wrote:If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
On Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
Jarrett Billingsley wrote:On Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
Lutger wrote:Jarrett Billingsley wrote:I think moving forward D2 will be the norm, so I suggest going with dmd1 and dmd dir names and dmd1 and dmd binary names. AndreiOn Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
On Thu, Jul 23, 2009 at 2:23 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Lutger wrote:Yeah, let me know when that happens. Until then, I'd like to continue to be able to use my build tools that were designed for D1 without having to modify all their config files.Jarrett Billingsley wrote:I think moving forward D2 will be the norm, so I suggest going with dmd1 and dmd dir names and dmd1 and dmd binary names.On Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
Jarrett Billingsley wrote:Yeah, let me know when that happens. Until then, I'd like to continue to be able to use my build tools that were designed for D1 without having to modify all their config files.I don't know what build tools you're using, but consider make: ------ win32.mak --------- DMD=\dmd\windows\bin\dmd target : foo.obj foo.obj : foo.d $(DMD) -c foo -------------------------- Now, we can drive it with a makefile that customizes the macros like so: ------ makefile ---------- target: make -fwin32.mak DMD=\dmd2\windows\bin\dmd -------------------------- I use this technique a lot. You can also have makefiles recursively call themselves and reset the macros: ---------- makefile -------- DMD=\dmd\windows\bin\dmd target : foo.obj target2: make target DMD=\dmd2\windows\bin\dmd foo.obj : foo.d $(DMD) -c foo ----------------------------
Jul 23 2009
On Thu, Jul 23, 2009 at 3:22 PM, Walter Bright<newshound1 digitalmars.com> wrote:Jarrett Billingsley wrote:Walter, I'm pretty shocked by this response. How long have Bud and DSSS existed? D users who *don't* use them are the exception. You even patched DMD recently to make it easier for xfBuild to do its job. This "D" programming language is great because it obviates make. You should try it sometime! I think you might like it ;)Yeah, let me know when that happens. =A0Until then, I'd like to continue to be able to use my build tools that were designed for D1 without having to modify all their config files.I don't know what build tools you're using, but consider make:
Jul 23 2009
Jarrett Billingsley wrote:This "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 23 2009
On Thu, Jul 23, 2009 at 3:54 PM, Walter Bright<newshound1 digitalmars.com> wrote:Jarrett Billingsley wrote:So editing every make file you have is better? :PThis "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 23 2009
On Thu, Jul 23, 2009 at 4:03 PM, Jarrett Billingsley<jarrett.billingsley gmail.com> wrote:On Thu, Jul 23, 2009 at 3:54 PM, Walter Bright<newshound1 digitalmars.com> wrote:Ah, nevermind.Jarrett Billingsley wrote:So editing every make file you have is better? =A0:PThis "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 23 2009
Walter Bright wrote:Jarrett Billingsley wrote:So that's the killer feature of make? I don't know about you, but I always use only one D compiler. It's in $PATH, and the actual binary can be I-don't-know-where. Now nobody is saying that dsss/rebuild/bud/xfbuild eliminate _all_ uses of make. But for a typical D project, writing makefiles is pure bloat and a waste of time.This "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 23 2009
Walter Bright wrote:Jarrett Billingsley wrote:I don't do it that way. I can't imagine when you would mix D1 and D2 in a single build. Instead, I have a set of trivial scripts to change the symlink for the 'dmd' directory. Nothing else needs to be aware of the compiler version. From then on, I just use bud. I'll be pretty annoyed if the D2 compiler changes its name to DMD2.This "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 24 2009
On 2009-07-24 03:51:50 -0400, Don <nospam nospam.com> said:Walter Bright wrote:My opinion is that the best way forward is to have dmd1, dmd2, and a symlink called dmd to one or the other. That way in a makefile you can explicitly request for one or the other if you want, but you don't have to: you can switch at will. -- Michel Fortin michel.fortin michelf.com http://michelf.com/Jarrett Billingsley wrote:I don't do it that way. I can't imagine when you would mix D1 and D2 in a single build. Instead, I have a set of trivial scripts to change the symlink for the 'dmd' directory. Nothing else needs to be aware of the compiler version. From then on, I just use bud. I'll be pretty annoyed if the D2 compiler changes its name to DMD2.This "D" programming language is great because it obviates make.Ok, now about make's ability to switch compilers without having to edit config files?
Jul 24 2009
Walter Bright wrote:I don't know what build tools you're using, but consider make: ------ win32.mak --------- DMD=\dmd\windows\bin\dmd target : foo.obj foo.obj : foo.d $(DMD) -c foo --------------------------And for GNU make, it uses the variables $(DC) and $(DMD) where DC is the D compiler (like CC) and DMD the wrapper. The annoying part is changing the DFLAGS for the compiler, and/or translating any needed linker flags for the wrapper... ifeq ("$(COMPILER)","DMD") DC ?= dmd DMD ?= dmd DFLAGS = -O -g version=-version output=-of$ endif ifeq ("$(COMPILER)","LDC") DC ?= ldc DMD ?= ldmd DFLAGS = -O version=-d-version output=-of=$ endif ifeq ("$(COMPILER)","GDC") DC ?= gdc DMD ?= gdmd DFLAGS = -O2 -g version=-fversion output=-o $ endif %.o:%.d $(DC) $(DFLAGS) -c $(output) $< --anders
Aug 01 2009
Andrei Alexandrescu wrote:Lutger wrote:Also fine, as long as they are different to ease more complex setups, plus it will make it much more convenient to create linux packages for this.Jarrett Billingsley wrote:I think moving forward D2 will be the norm, so I suggest going with dmd1 and dmd dir names and dmd1 and dmd binary names. AndreiOn Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
On Thu, Jul 23, 2009 at 12:09 PM, Lutger<lutger.blijdestijn gmail.com> wrote:Andrei Alexandrescu wrote:Shouldn't the strategy taken be something more akin to what multi-version packages like python and perl already do? They don't just automatically rename old python to be python<OldVersion> after every new version comes out. On windows they call it python.exe but put it in a different directory. On versions of linux I think there are some fancy schemes for setting up symlinks to particular versions to be the default. Can't recall what that system was called. "Defaults" or something like it. Anyway, seems like on linux dmd should work with that rather than just going and changing the names of exes according to whim. --bbLutger wrote:Also fine, as long as they are different to ease more complex setups, plus it will make it much more convenient to create linux packages for this.Jarrett Billingsley wrote:I think moving forward D2 will be the norm, so I suggest going with dmd1 and dmd dir names and dmd1 and dmd binary names. AndreiOn Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
Bill Baxter wrote:On Thu, Jul 23, 2009 at 12:09 PM, Lutger<lutger.blijdestijn gmail.com> wrote:Yes, I admit this is the preferred and in the end only sane way of doing it. (i have set it up like this come to think of it, don't know why). For people for which there is no default because they do work with both it is less nice though, imho.Andrei Alexandrescu wrote:Shouldn't the strategy taken be something more akin to what multi-version packages like python and perl already do? They don't just automatically rename old python to be python<OldVersion> after every new version comes out. On windows they call it python.exe but put it in a different directory. On versions of linux I think there are some fancy schemes for setting up symlinks to particular versions to be the default. Can't recall what that system was called. "Defaults" or something like it. Anyway, seems like on linux dmd should work with that rather than just going and changing the names of exes according to whim. --bbLutger wrote:Also fine, as long as they are different to ease more complex setups, plus it will make it much more convenient to create linux packages for this.Jarrett Billingsley wrote:I think moving forward D2 will be the norm, so I suggest going with dmd1 and dmd dir names and dmd1 and dmd binary names. AndreiOn Thu, Jul 23, 2009 at 1:59 PM, Walter Bright<newshound1 digitalmars.com> wrote:That would be very convenient, please consider this.Michel Fortin wrote:Will you rename the DMD2 compiler to 'dmd2' as well?If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
Jarrett Billingsley wrote:Will you rename the DMD2 compiler to 'dmd2' as well?No. If they're in different directory trees, there's no reason to. After all, that's the whole point of having directories!
Jul 23 2009
On Thu, Jul 23, 2009 at 12:13 PM, Walter Bright<newshound1 digitalmars.com> wrote:Jarrett Billingsley wrote:That seems to be the way they do things in Windows, but usually they set up various extra symlinks on unix systems so that you can call a particular version of a program when there are multiple installed. Like gcc-2.95, etc. --bbWill you rename the DMD2 compiler to 'dmd2' as well?No. If they're in different directory trees, there's no reason to. After all, that's the whole point of having directories!
Jul 23 2009
On 2009-07-23 13:59:46 -0400, Walter Bright <newshound1 digitalmars.com> said:Michel Fortin wrote:I know. But the OS X installer I see on dsource doesn't seem to reflect that: it always install at /usr/share/dmd/ (and /usr/share is a stange choice too). Now that I look at it, it seems to predate the switch to separate directories. -- Michel Fortin michel.fortin michelf.com http://michelf.com/If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts?I've been switching the directories to {dmd, dmd2} so they can coexist.
Jul 23 2009
On 7/23/09 12:32 PM, Michel Fortin wrote:On 2009-07-23 05:37:24 -0400, Jacob Carlborg <doob me.com> said:Sorry I haven't replied sooner I've been on vacation. I looked at a gdc installer and looked where it placed the compiler and did the same. I don't know where it's best to place the compiler. /Jacob CarlborgYes: http://www.dsource.org/projects/dmd-installer I'm still waiting for Walter to add the osx installer to the dmd download page.Speaking of that OS X DMD installer, are you sure installing it at /usr/share/dmd/ is a good idea? Normally /usr/share is reserved for architecture-independent data[1], not executable files. What about /usr/local/dmd with symlinks in /usr/local/bin for executables /usr/local/lib for phobos and druntime and /usr/local/man for man pages. Or perhaps install /Library/D/{dmd,dmd2} so the files are more user accessible and easy to change if you got the zip archive (/usr is a hidden dir on Mac OS X). If I'm not mistaken, both your D1 and D2 installer install at the same location and they will overwrite each other. I'd much prefer if D2 and D1 could coexist without having to go with a special installer or custom installation instructions. Otherwise it'll be hard for me to offer the choice between D1 and D2 in Xcode (and I certainly do want that choice to be available). Thoughts? [1]: http://www.pathname.com/fhs/2.2/fhs-4.11.html
Jul 31 2009
Jacob Carlborg wrote:You can use /opt/dmd and /opt/dmd2, if you don't want to use the regular file hierarchy in hier(7) DMD = /opt/dmd2/osx/bin/dmd Or you can use e.g. /usr/local/bin and rename to dmd2 and dmd2.conf (which takes some trickery...) DMD = dmd2 --andersSpeaking of that OS X DMD installer, are you sure installing it at /usr/share/dmd/ is a good idea? [...]I looked at a gdc installer and looked where it placed the compiler and did the same. I don't know where it's best to place the compiler.
Aug 01 2009
On 2009-08-01 04:41:38 -0400, Anders F Bjrklund <afb algonet.se> said:Jacob Carlborg wrote:In hier(7), it says that "/usr/local" is for "executables, libraries, etc. not included by the basic operating system", so I guess DMD fits this quite well. I'm preparing an installer for D for Xcode and made it install DMD at /usr/local/dmd and /usr/local/dmd2, with symlinks at /usr/local/bin/dmd (system-prefered version) /usr/local/bin/dmd1 (1.x) and /usr/local/bin/dmd2 (2.x). This makes it easy to choose the version you want within Xcode. For some reasons, the symlinks works fine with Xcode. But they aren't working from the command line (dmd complains that it can't find object.o). I've made a small C program to replace the symlink: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); } No more problem from the command line. -- Michel Fortin michel.fortin michelf.com http://michelf.com/You can use /opt/dmd and /opt/dmd2, if you don't want to use the regular file hierarchy in hier(7) DMD = /opt/dmd2/osx/bin/dmd Or you can use e.g. /usr/local/bin and rename to dmd2 and dmd2.conf (which takes some trickery...) DMD = dmd2Speaking of that OS X DMD installer, are you sure installing it at /usr/share/dmd/ is a good idea? [...]I looked at a gdc installer and looked where it placed the compiler and did the same. I don't know where it's best to place the compiler.
Aug 01 2009
Michel Fortin wrote:You can use /opt/dmd and /opt/dmd2, if you don't want to use the regular file hierarchy in hier(7)In hier(7), it says that "/usr/local" is for "executables, libraries, etc. not included by the basic operating system", so I guess DMD fits this quite well.I normally* use the regular /usr/local/bin and /usr/local/lib and so on, when using /usr/local and otherwise /opt for various vendor layouts... But I suppose /usr/local/dmd "works" just fine. Renaming dmd to dmd1 probably makes sense, once dmd2 is released, and switching with the symlink. Was using something similar to switch between the Phobos and Tango libraries in earlier versions. --anders * GDC was using /usr/bin, since it was sharing some files with /usr/bin/gcc already anyway.
Aug 01 2009
Sat, 1 Aug 2009 07:55:08 -0400, Michel Fortin wrote:On 2009-08-01 04:41:38 -0400, Anders F Bjrklund <afb algonet.se> said:Here's a nice document about directory layout in UNIX-like OSes: http://www.pathname.com/fhs/pub/fhs-2.3.html I think MacOS should follow this layout at least in part. In particular /usr/local/ is used for locally installed packages which otherwise respect the standard directory structure found in / or /usr/. That is, binaries go into /usr/local/bin/, libraries in /usr/local/lib/ etc. If a package wants to keep its own structure it's supposted to go into /opt/, like /opt/dmd2/whatever.Jacob Carlborg wrote:In hier(7), it says that "/usr/local" is for "executables, libraries, etc. not included by the basic operating system", so I guess DMD fits this quite well. I'm preparing an installer for D for Xcode and made it install DMD at /usr/local/dmd and /usr/local/dmd2, with symlinks at /usr/local/bin/dmd (system-prefered version) /usr/local/bin/dmd1 (1.x) and /usr/local/bin/dmd2 (2.x). This makes it easy to choose the version you want within Xcode. For some reasons, the symlinks works fine with Xcode. But they aren't working from the command line (dmd complains that it can't find object.o). I've made a small C program to replace the symlink: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); } No more problem from the command line.You can use /opt/dmd and /opt/dmd2, if you don't want to use the regular file hierarchy in hier(7) DMD = /opt/dmd2/osx/bin/dmd Or you can use e.g. /usr/local/bin and rename to dmd2 and dmd2.conf (which takes some trickery...) DMD = dmd2Speaking of that OS X DMD installer, are you sure installing it at /usr/share/dmd/ is a good idea? [...]I looked at a gdc installer and looked where it placed the compiler and did the same. I don't know where it's best to place the compiler.
Aug 01 2009
On 2009-08-01 20:15:41 -0400, Sergey Gromov <snake.scaly gmail.com> said:Here's a nice document about directory layout in UNIX-like OSes: http://www.pathname.com/fhs/pub/fhs-2.3.html I think MacOS should follow this layout at least in part. In particular /usr/local/ is used for locally installed packages which otherwise respect the standard directory structure found in / or /usr/. That is, binaries go into /usr/local/bin/, libraries in /usr/local/lib/ etc. If a package wants to keep its own structure it's supposted to go into /opt/, like /opt/dmd2/whatever.Well, given that this is Mac OS X we could also put this in /Library/D/dmd and /Library/D/dmd2, two directories which aren't hidden by the file browser. Then put symlinks in /usr/local/bin and /usr/local/lib pointing there. Users will then be able to upgrade without an installer by simply replacing the folder at /Library/D/dmd & dmd2 with a newly downloaded one. I think that's better than /opt, as /opt isn't present by default on Mac OS X, isn't hidden by the Finder when present (contrary to all other "UNIX" directories at the root) and thus would look a little out of place on the hard drive. And there's already /Library/Python, /Library/PHP and /Library/Ruby in that /Library directory to set a precedent. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 01 2009
Michel Fortin wrote:Well, given that this is Mac OS X we could also put this in /Library/D/dmd and /Library/D/dmd2, two directories which aren't hidden by the file browser. Then put symlinks in /usr/local/bin and /usr/local/lib pointing there. Users will then be able to upgrade without an installer by simply replacing the folder at /Library/D/dmd & dmd2 with a newly downloaded one.That's how the zip files work, yes ? Possibly PATH instead of symlinks. Main difference between /Library/D and ~ is that it requires "admin" privileges while anyone can install into ~/dmd (even if not an admin) The /usr installer for GDC requires root, so it auths as admin first. Then again that gdc needed to be installed into system gcc locations, so it wasn't really relocatable like the upstream tarball from dgcc.I think that's better than /opt, as /opt isn't present by default on Mac OS X, isn't hidden by the Finder when present (contrary to all other "UNIX" directories at the root) and thus would look a little out of place on the hard drive. And there's already /Library/Python, /Library/PHP and /Library/Ruby in that /Library directory to set a precedent.I think /Library/{Python,Perl,Ruby} are mostly used for user modules ? The actual interpreters are normally installed under /usr or /usr/local Possibly symlinked, in case of a framework installation (like Python's) You could also use the /Developer hierarchy for installing compilers. But I would use a "commandline" directory for a commandline tool, rather than having it Finder-browsable. It might make sense for docs and such. --anders
Aug 02 2009
On 8/2/09 03:40, Michel Fortin wrote:On 2009-08-01 20:15:41 -0400, Sergey Gromov <snake.scaly gmail.com> said:I think I like /usr/local best. /Library is used for resources: "The Library directory is a special directory used to store application-specific and system-specific resources". What about /Applications?Here's a nice document about directory layout in UNIX-like OSes: http://www.pathname.com/fhs/pub/fhs-2.3.html I think MacOS should follow this layout at least in part. In particular /usr/local/ is used for locally installed packages which otherwise respect the standard directory structure found in / or /usr/. That is, binaries go into /usr/local/bin/, libraries in /usr/local/lib/ etc. If a package wants to keep its own structure it's supposted to go into /opt/, like /opt/dmd2/whatever.Well, given that this is Mac OS X we could also put this in /Library/D/dmd and /Library/D/dmd2, two directories which aren't hidden by the file browser. Then put symlinks in /usr/local/bin and /usr/local/lib pointing there. Users will then be able to upgrade without an installer by simply replacing the folder at /Library/D/dmd & dmd2 with a newly downloaded one. I think that's better than /opt, as /opt isn't present by default on Mac OS X, isn't hidden by the Finder when present (contrary to all other "UNIX" directories at the root) and thus would look a little out of place on the hard drive. And there's already /Library/Python, /Library/PHP and /Library/Ruby in that /Library directory to set a precedent.
Aug 03 2009
On 2009-08-03 06:59:14 -0400, Jacob Carlborg <doob me.com> said:I think I like /usr/local best.I like /usr/local best too./Library is used for resources:"TheLibrary directory is a special directory used to store application-specific and system-specific resources".Indeed.What about /Applications?I thought that was for applications. DMD isn't an appliction, it's a command-line tool. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 03 2009
Michel Fortin wrote:The objection (if any) was mostly about "/usr/local/dmd/osx/bin" vs /usr/local/bin, but using /usr/local/{dmd,dmd2} should be OK.I think I like /usr/local best.I like /usr/local best too.Such as the language extensions in /Library/Perl and /Library/Python already mentioned, elsewhere in /usr/lib/perl5 and /usr/lib/python2.XLibrary directory is a special directory used to store application-specific and system-specific resources".Indeed.And even if it was, it would probably go in /Developer anyway ? Like /Developer/Applications/CodeBlocks.app does, for instance. --andersWhat about /Applications?I thought that was for applications. DMD isn't an appliction, it's a command-line tool.
Aug 03 2009
On 8/3/09 14:32, Anders F Bjrklund wrote:Michel Fortin wrote:I was thinking about using /usr/local/{dmd,dmd2} and then create symlinks to /usr/local/bin. But that will create problems with the dmd.conf because it also needs a symlink in /usr/local/bin and then the conf file for dmd and dmd1 will conflict.The objection (if any) was mostly about "/usr/local/dmd/osx/bin" vs /usr/local/bin, but using /usr/local/{dmd,dmd2} should be OK.I think I like /usr/local best.I like /usr/local best too.Such as the language extensions in /Library/Perl and /Library/Python already mentioned, elsewhere in /usr/lib/perl5 and /usr/lib/python2.XLibrary directory is a special directory used to store application-specific and system-specific resources".Indeed.And even if it was, it would probably go in /Developer anyway ? Like /Developer/Applications/CodeBlocks.app does, for instance. --andersWhat about /Applications?I thought that was for applications. DMD isn't an appliction, it's a command-line tool.
Aug 07 2009
On 2009-08-07 08:05:04 -0400, Jacob Carlborg <doob me.com> said:On 8/3/09 14:32, Anders F Bjrklund wrote:The solution is to create a "symlink program" and drop it in /usr/local/bin. I know it works; I wrote one to do just that: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); } -- Michel Fortin michel.fortin michelf.com http://michelf.com/Michel Fortin wrote:I was thinking about using /usr/local/{dmd,dmd2} and then create symlinks to /usr/local/bin. But that will create problems with the dmd.conf because it also needs a symlink in /usr/local/bin and then the conf file for dmd and dmd1 will conflict.The objection (if any) was mostly about "/usr/local/dmd/osx/bin" vs /usr/local/bin, but using /usr/local/{dmd,dmd2} should be OK.I think I like /usr/local best.I like /usr/local best too.
Aug 07 2009
Michel Fortin wrote:I did that for my linux package, but used shell instead. Then the dmd.conf was a link back to the real config file, to /etc/dmd.conf for dmd and to /etc/dmd2.conf for dmd2... /usr/bin/dmd2 -> /usr/libexec/dmd2/dmd /usr/libexec/dmd2/dmd.conf -> /etc/dmd2.conf Then the conf files didn't conflict anymore. --andersThe solution is to create a "symlink program" and drop it in /usr/local/bin. I know it works; I wrote one to do just that: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); }The objection (if any) was mostly about "/usr/local/dmd/osx/bin" vs /usr/local/bin, but using /usr/local/{dmd,dmd2} should be OK.I was thinking about using /usr/local/{dmd,dmd2} and then create symlinks to /usr/local/bin. But that will create problems with the dmd.conf because it also needs a symlink in /usr/local/bin and then the conf file for dmd and dmd1 will conflict.
Aug 07 2009
On 8/7/09 17:32, Anders F Bjrklund wrote:Michel Fortin wrote:If I understand you correctly you have a symlink "/usr/bin/dmd2" pointing to "/usr/libexec/dmd2/dmd" and then a symlink "/usr/libexec/dmd2/dmd.conf" pointing to "/etc/dmd2.conf". I can't see how that would work, correct me if I'm wrong: dmd will only search for a conf file named dmd.conf in the same path as the dmd executable, in /etc or in the user home directory. dmd will not find the file in /etc because it's named "dmd2.conf". The file "usr/libexec/dmd2/dmd.conf" will not work because the dmd.conf will needs to be in the same directory as the symlink and not the actual executable, this was the first I tried. /Jacob CarlborgI did that for my linux package, but used shell instead. Then the dmd.conf was a link back to the real config file, to /etc/dmd.conf for dmd and to /etc/dmd2.conf for dmd2... /usr/bin/dmd2 -> /usr/libexec/dmd2/dmd /usr/libexec/dmd2/dmd.conf -> /etc/dmd2.conf Then the conf files didn't conflict anymore. --andersThe solution is to create a "symlink program" and drop it in /usr/local/bin. I know it works; I wrote one to do just that: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); }The objection (if any) was mostly about "/usr/local/dmd/osx/bin" vs /usr/local/bin, but using /usr/local/{dmd,dmd2} should be OK.I was thinking about using /usr/local/{dmd,dmd2} and then create symlinks to /usr/local/bin. But that will create problems with the dmd.conf because it also needs a symlink in /usr/local/bin and then the conf file for dmd and dmd1 will conflict.
Aug 12 2009
Jacob Carlborg wrote:Right, /usr/libexec/dmd2/dmd is the actual program. And /usr/bin/dmd2 was a wrapper that exec'd it... exec /usr/libexec/dmd2/dmd "$*" Guess one could use the same workaround for moving dmd over to "dmd1", and make dmd into a symlink ? --anders http://www.digitalmars.com/d/archives/digitalmars/D/announce/DMD_1.029_and_2.013_releases_11949.html#N11988If I understand you correctly you have a symlink "/usr/bin/dmd2" pointing to "/usr/libexec/dmd2/dmd" and then a symlink "/usr/libexec/dmd2/dmd.conf" pointing to "/etc/dmd2.conf". I can't see how that would work, correct me if I'm wrong: dmd will only search for a conf file named dmd.conf in the same path as the dmd executable, in /etc or in the user home directory. dmd will not find the file in /etc because it's named "dmd2.conf". The file "usr/libexec/dmd2/dmd.conf" will not work because the dmd.conf will needs to be in the same directory as the symlink and not the actual executable, this was the first I tried.The solution is to create a "symlink program" and drop it in /usr/local/bin. I know it works; I wrote one to do just that: #include <unistd.h> int main(unsigned int argc, char **argv) { argv[0] = "/usr/local/dmd/osx/bin/dmd"; execv("/usr/local/dmd/osx/bin/dmd", argv); }I did that for my linux package, but used shell instead. Then the dmd.conf was a link back to the real config file, to /etc/dmd.conf for dmd and to /etc/dmd2.conf for dmd2... /usr/bin/dmd2 -> /usr/libexec/dmd2/dmd /usr/libexec/dmd2/dmd.conf -> /etc/dmd2.conf Then the conf files didn't conflict anymore. --anders
Aug 12 2009
On 2009-08-12 19:37:13 -0400, Anders F Bjrklund <afb algonet.se> said:Guess one could use the same workaround for moving dmd over to "dmd1", and make dmd into a symlink ?That's something I'd really like to see. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 12 2009
Michel Fortin wrote:It's done the same with GCC, too: /usr/bin/gcc -> gcc-4.0 /usr/bin/gcc-3.3 /usr/bin/gcc-4.0 /usr/bin/gcc2 /usr/bin/gcc3 Was even a gcc_select(8) program. --anders PS. But now it's all gcc-4.2 instead, and with or without LLVM is the question. Of course neither of the Apple compilers works very well with GDC any longer...Guess one could use the same workaround for moving dmd over to "dmd1", and make dmd into a symlink ?That's something I'd really like to see.
Aug 13 2009
On 2009-08-07 08:05:04 -0400, Jacob Carlborg <doob me.com> said:I was thinking about using /usr/local/{dmd,dmd2} and then create symlinks to /usr/local/bin. But that will create problems with the dmd.conf because it also needs a symlink in /usr/local/bin and then the conf file for dmd and dmd1 will conflict.Also, could you make symlinks for "dmd" (prefered version), "dmd1" and "dmd2" in /usr/local/bin ? This should allow projects to use explicitely dmd1 or dmd2 when needed, while the user could rebind dmd to one or the other depending on his needs. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 07 2009
Walter Bright wrote:http://www.reddit.com/r/programming/comments/93jh5/ask_proggit_the_d_program ing_language_looks/Let me start with an example. Some time ago I need a script to get and process some data. I trough why not use D, but I couldn't find a function in the standard library which would get a simple web page with http. Instead of find and downloading other libraries I switched to peal and had it running in no time. I think it is the choice of problem domain for D. Successful language are typical the first moves in a new and popular problem domain. FORTRAN - vector processing. PHP - server side web programing. Java - platform independent client side programing. etc. If you want people to switch you need provide the tools for solving this problems. To get the Fortran crowd D needs faster vector processing. To get the PHP crowd D needs libraries that support web programming. To get the java crowd, it should be possible to run platform independent D programs in you browser. etc. I know the real focus for D system programing and the C++ people. I think one of D's strongest points for people to make the switch is build in unit testing. (at least this is the strongest point for me) But the very simple implementation of unit testing in D nearly ruin the advantage it gives. (see suggestion from the wishlist below) C++ have a lot of good libraries to solve all type of problems, for me it wouldn't be a problem if I knew that the D libraries would be a much better quality. A indicator for this would be if I knew that the library was properly unit tested. A simple way to ensure that could if the compiler issued a error/warning if a function had no unit tests or contracts. What follows is some unit test suggestions from http://all-technology.com/eigenpolls/dwishlist Because I would like to hear your opinion about them. ** unit test & code separation I think it would be more useful if the code and the unit test where two separate binaries. Sometimes you need to move the production binary to another machine/environment. It would be nice if one could move the test binary with it and test that everything works. It would also allow for arguments to the test binary, so that you would be able to run a specific unit test. ** black box unit testing The d compiler should enforce black box unit tests. Which is unit tests that only use the classes exposed interface.(public, protected) Together with 100% unit test coverage it helps ensure that the code is modular,decoupled and that you can change the private parts without changing the unit tests. For those how is not ready for this high code standard, there might be a --allow-white-box switch. ** Unit test isolation I would like to be able to isolate the unit test, so that if one fail the next still runs. unittest() { test("test1") { assert(...); assert(...) } test("test1") { assert(...); assert(...) } for (i=3;i<10;i++) { test("test"~i) { assert(...); assert(...) } } } ** Unit test measurements In combination with test isolation it would be nice to have d output memory and time used in each unit test. -- Join me on CrowdNews http://crowdnews.eu/users/addGuide/42/ Facebook http://www.facebook.com/profile.php?id=1198821880 Linkedin http://www.linkedin.com/pub/0/117/a54 Mandala http://www.mandala.dk/view-profile.php4?profileID=7660
Jul 23 2009
Knud Soerensen wrote:Some time ago I need a script to get and process some data. I trough why not use D, but I couldn't find a function in the standard library which would get a simple web page with http. Instead of find and downloading other libraries I switched to peal and had it running in no time. I think it is the choice of problem domain for D.I'd love to have some functions in Phobos that do this. Can you write a module and contribute it? Phobos is definitely short on a lot of networking functionality.I know the real focus for D system programing and the C++ people. I think one of D's strongest points for people to make the switch is build in unit testing. (at least this is the strongest point for me) But the very simple implementation of unit testing in D nearly ruin the advantage it gives. (see suggestion from the wishlist below)Even at its very simple support, it's a huge win. It raises the bar on what is minimally acceptable, and has been responsible for a big improvement in the quality of Phobos.A simple way to ensure that could if the compiler issued a error/warning if a function had no unit tests or contracts.I worry that such would be crying wolf. But dmd does have a coverage analyzer built in - which I think is more useful. It'll show which lines were executed by the unit tests, and which were not.What follows is some unit test suggestions from http://all-technology.com/eigenpolls/dwishlist Because I would like to hear your opinion about them. ** unit test & code separation I think it would be more useful if the code and the unit test where two separate binaries. Sometimes you need to move the production binary to another machine/environment. It would be nice if one could move the test binary with it and test that everything works. It would also allow for arguments to the test binary, so that you would be able to run a specific unit test.I made the decision at one point that unit tests weren't there to test that the compiler generated code correctly, they were to test the logic of the user code. Hence, one does a separate build for unit tests than production release. The release version should get the black box tests, not unit tests.** black box unit testing The d compiler should enforce black box unit tests. Which is unit tests that only use the classes exposed interface.(public, protected) Together with 100% unit test coverage it helps ensure that the code is modular,decoupled and that you can change the private parts without changing the unit tests. For those how is not ready for this high code standard, there might be a --allow-white-box switch.The compiler doesn't need to help here. There's nothing preventing one from using unittests in this manner. Just import the .di file, which is the exposed interface, then write a unit test block.** Unit test isolation I would like to be able to isolate the unit test, so that if one fail the next still runs.You can do this by simply not using "assert" for the actual test. Use: if (!x) writeln("test for x failed"); instead of: assert(x); You can, of course, make a template like Andrei's enforce() to make the if test and message a bit more convenient.** Unit test measurements In combination with test isolation it would be nice to have d output memory and time used in each unit test.Use the -profile switch.
Jul 23 2009
Walter Bright wrote:Knud Soerensen wrote:...It's interesting why unittest (and assert) are such big success. My idea is that it's not in spite of, but because of their utter simplicity. I speculate that if it would have been different, for example if you would had to create a new file for a unittest, it would not have been used so much. ...I think one of D's strongest points for people to make the switch is build in unit testing. (at least this is the strongest point for me) But the very simple implementation of unit testing in D nearly ruin the advantage it gives. (see suggestion from the wishlist below)Even at its very simple support, it's a huge win. It raises the bar on what is minimally acceptable, and has been responsible for a big improvement in the quality of Phobos.But within sight there is something much better. druntime defines a function setAssertHandler to configure a user defined function for handling assertions! Combine this with version(unittest) and the Runtime.moduleUnitTester callback et voila!: profit* I still see two major points of improvement: - unittests are anonymous things. It would be a big improvement to be able to say unittest("Test foobar") { } and retrieve the named test via the runtime provided hooks - all unittests from one module are lumped together in it's ModuleInfo object. I would rather like to see an array of named unittests instead. The rationale for these improvements is that the language and standard library only defines very minimal, low impact ways of writing tests. At the same time, the building blocks are provided to create more advanced tools. This way you can also start out writing simple tests, and then not have to rewrite those again when you want to use some fancy continuous integration suite for D. At the moment, it's simply not possible to progress to more elaborate testing without breaking everything and starting from scratch. * Well I think so, I haven't been able to make use of it (segfaults) but it would be sweet.** Unit test isolation I would like to be able to isolate the unit test, so that if one fail the next still runs.You can do this by simply not using "assert" for the actual test. Use: if (!x) writeln("test for x failed"); instead of: assert(x); You can, of course, make a template like Andrei's enforce() to make the if test and message a bit more convenient.
Jul 23 2009
Lutger wrote:It's interesting why unittest (and assert) are such big success. My idea is that it's not in spite of, but because of their utter simplicity. I speculate that if it would have been different, for example if you would had to create a new file for a unittest, it would not have been used so much.I tend to agree. I've found over and over, that if you drive things down to their simplest essence, they'll get wide adoption. If someone needs to read a manual with long lists of options, they'll pass it by. For instance, look at the installer thing. I think that downloading a zip file, and unzipping it, is so trivial. Yet this seems to be a blocker for people using D, over and over I hear about how hard it is to install. I find this baffling. But yet, it's obviously an issue.
Jul 24 2009
On Fri, 24 Jul 2009 05:26:39 -0400, Walter Bright <newshound1 digitalmars.com> wrote:Lutger wrote:Downloading, unzipping (where?), setting up your path, marking the binary as executable (on *nix). Much easier to use the OS's installer and let the package tell me how to set it up. Getting the files and expanding them isn't the difficult part :) -SteveIt's interesting why unittest (and assert) are such big success. My idea is that it's not in spite of, but because of their utter simplicity. I speculate that if it would have been different, for example if you would had to create a new file for a unittest, it would not have been used so much.I tend to agree. I've found over and over, that if you drive things down to their simplest essence, they'll get wide adoption. If someone needs to read a manual with long lists of options, they'll pass it by. For instance, look at the installer thing. I think that downloading a zip file, and unzipping it, is so trivial. Yet this seems to be a blocker for people using D, over and over I hear about how hard it is to install. I find this baffling. But yet, it's obviously an issue.
Jul 24 2009
Walter Bright wrote:Yes, but the chose is not about unit test or no unit test. It is between using D with its very simple unit test framework or C++/java/etc with a very good unit testing framework. I think that D should provide a framework on the same level or maybe just make the best unit testing framework on the planet.I know the real focus for D system programing and the C++ people. I think one of D's strongest points for people to make the switch is build in unit testing. (at least this is the strongest point for me) But the very simple implementation of unit testing in D nearly ruin the advantage it gives. (see suggestion from the wishlist below)Even at its very simple support, it's a huge win. It raises the bar on what is minimally acceptable, and has been responsible for a big improvement in the quality of Phobos.Yes, the coverage analyzer is very good, but how do you ensure that the library developers actually use it ?? The feature should be introduce slowly, by first printing a warning when a testing binary was build. Then step it up to a error for testing binary. Then a warning for production binaries and in a dissent future also errors on production binaries. Already at the first step, we would see if the D community find it useful. In its last step it would unsure that everybody using some unknown D code would know that it had some level of test coverage and quality. It is not as fine masked as 100% coverage test but would ensure that ever function had some test code and that without run a coverage analyzes. How hard do you think it would be to make ?A simple way to ensure that could if the compiler issued a error/warning if a function had no unit tests or contracts.I worry that such would be crying wolf. But dmd does have a coverage analyzer built in - which I think is more useful. It'll show which lines were executed by the unit tests, and which were not.Running unit test in another environment is god for testing if the assumptions you make in your code about the environment is correct.What follows is some unit test suggestions from http://all-technology.com/eigenpolls/dwishlist Because I would like to hear your opinion about them. ** unit test & code separation I think it would be more useful if the code and the unit test where two separate binaries. Sometimes you need to move the production binary to another machine/environment. It would be nice if one could move the test binary with it and test that everything works. It would also allow for arguments to the test binary, so that you would be able to run a specific unit test.I made the decision at one point that unit tests weren't there to test that the compiler generated code correctly, they were to test the logic of the user code. Hence, one does a separate build for unit tests than production release.The release version should get the black box tests, not unit tests.Yes, you can do that. But why should you have to jump trough loops to write good test code. I think the default behavior should support writing good modular tests. Imagine we have a team with 20 programmers working a big project. The project standard for unit testing is to include .di file and write unit test on the public interface. Now imagine one bad programmer broke the standard and wrote a unit test on a private function. Now, how would you discover that, without going trough every d file ? If it is default behavior was not to allow unit testing private function then the bad programmer would have to use the --allow-white-box switch and you could just compile without it to discover the problem. -- Join me on CrowdNews http://crowdnews.eu/users/addGuide/42/ Facebook http://www.facebook.com/profile.php?id=1198821880 Linkedin http://www.linkedin.com/pub/0/117/a54 Mandala http://www.mandala.dk/view-profile.php4?profileID=7660** black box unit testing The d compiler should enforce black box unit tests. Which is unit tests that only use the classes exposed interface.(public, protected) Together with 100% unit test coverage it helps ensure that the code is modular,decoupled and that you can change the private parts without changing the unit tests. For those how is not ready for this high code standard, there might be a --allow-white-box switch.The compiler doesn't need to help here. There's nothing preventing one from using unittests in this manner. Just import the .di file, which is the exposed interface, then write a unit test block.
Jul 23 2009
On Thu, 23 Jul 2009 22:06:23 +0200, Knud Soerensen wrote:Walter Bright wrote:But those languages don't have Unit testing. There are libraries that let you do Unit testing in those languages, but it isn't the language. Hence the creation of DUnit.Yes, but the chose is not about unit test or no unit test. It is between using D with its very simple unit test framework or C++/java/etc with a very good unit testing framework. I think that D should provide a framework on the same level or maybe just make the best unit testing framework on the planet.I know the real focus for D system programing and the C++ people. I think one of D's strongest points for people to make the switch is build in unit testing. (at least this is the strongest point for me) But the very simple implementation of unit testing in D nearly ruin the advantage it gives. (see suggestion from the wishlist below)Even at its very simple support, it's a huge win. It raises the bar on what is minimally acceptable, and has been responsible for a big improvement in the quality of Phobos.
Jul 23 2009
"Knud Soerensen" <4tuu4k002 sneakemail.com> wrote in message news:h49mfs$vf2$1 digitalmars.com...Some time ago I need a script to get and process some data. I trough why not use D, but I couldn't find a function in the standard library which would get a simple web page with http. Instead of find and downloading other libraries I switched to peal and had it running in no time......** Unit test isolation I would like to be able to isolate the unit test, so that if one fail the next still runs.You may want to keep an eye on my SemiTwist D Tools http://www.dsource.org/projects/semitwist/ I haven't gotten around to releasing it yet, but it includes an alternate to assert that delays the "exit app" until you tell it to: int x = 7; mixin(deferAssert!("x == 9")); mixin(deferAssert!("2+2==5", "Reality is broken")); flushAsserts(); // Can put this at the beginning of main to wait for all unittests to run before bailing. // Now you get both errors, not just the first one. Unfortunately I wasn't able to get around the awkward "mixin" part though. (It also doesn't seem to work inside in{} out{} blocks, not sure why yet, I think there may be some limitation I'm not aware of about the code allowed in those.) In the same project I'm also working on a library that will provide, with one import, a full kitchen-sink scripting-style environment that should make the tasks like your example above much much easier in D.
Jul 23 2009
Walter Bright:Lazy parameter evaluation may turn out to be a bad idea, it doesn't seem to have found its "groove" anywhere.<Lazy parameters allow me to implement a poor's man list comprehensions. Once list comprehensions are built-in, I don't need lazy parameters much anymore. Why list comprehensions are very useful: for a language it's important to "scale up", it means it can be used to build large programs/systems, you seem aware of this. But in a modern language it's also very important to "scale down", that is to allow to write small functions/programs with less code an in a simple way. Many programs are small, and even large programs are made of small functions. Note: "Scala", means "scalable language", it means it can be used for small programs too.The flattening thing is a problem. The rest can be done with better library support.<A handy syntax to unpack too may be very useful, and it can't be done with a library: a, b, c = foo() a, d = [1, 2]There's no nice way to assert that a template or compile time function raises a certain compile time assert/error.* Unit testing (not at compile time,<<You can do testing at compile time with static asserts.<I agree that D's built-in unit testing is basic. But the fact that it exists *at all* is a huge improvement for a programming language.<in future Scala too). They are the languages D will be compared to. D will not be compared much to C/C++. Today improving a little over C++ is not enough. D's built-in unit testing is not enough, it misses few important things. My suggestion is not to add more built-in unittest capabilities to D, but to do the opposite: to remove the built-in unit testing from D and replace it with enough means (reflection, and what else) necessary to add a simple but sufficiently good unit testing module to Phobos. This is a situation where teaching fishing is better. (It may be possible that no things have to be added to D. Then it's just a matter to see such module written by someone and added to Phobos). ----------------------- Steven Schveighoffer:The one thing I think is missing from D in this area is struct interfaces.<----------------------- Lutger:It's interesting why unittest (and assert) are such big success. My idea is that it's not in spite of, but because of their utter simplicity. I speculate that if it would have been different, for example if you would had to create a new file for a unittest, it would not have been used so much.<It's another example of scaling. A good unit test system is the one that allows you to write quickly and in a very simple way simple tests. And to use them later to build more and more complex unit testing as the program gets bigger. At the moment D unit testing is fit for small purposes only, but not for the larger ones (Python docstests are fit for even small purposes, you can use it for unit testing even if your program is 15 lines long). ----------------------- Walter Bright:For instance, look at the installer thing. I think that downloading a zip file, and unzipping it, is so trivial. Yet this seems to be a blocker for people using D, over and over I hear about how hard it is to install. I find this baffling. But yet, it's obviously an issue.<Most people don't has much problems installing the DMD compiler on Windows, or LDC on Ubuntu. The problem comes just later, when such people look for a way to have a complete system (toolchain), with IDE, etc. Eventually D will need a handy bundle with the basic tools to program (the compiler is just one of them). ----------------------- Knud Soerensen:Now imagine one bad programmer broke the standard and wrote a unit test on a private function.<Unit tests are part of the code, part of the program itself. Many times it's better to keep tests as close as possible to the code they test. ----------------------- Walter Bright:It may indeed be the syntax, but consider that no other language adopted those constructs. There was a proposal to add contracts to C++0x which died. I added them to Digital Mars C++ and nobody cared.<A way to solve this problem is to add features (to D2), and then later remove them (to D3) if they aren't appreciated. This breaks backward compatibility, as D2 does on D1. Or even (silly idea) adding features to D1 may be good to test such features to see if they are worth addign to D2 :-) Using D1 as experimental field... ----------------------- Michiel Helvensteijn:I don't know a compelling use-case either. But that doesn't mean there isn't any. Nor are there any real dangers. Arbitrarily restricting the possibilities of D doesn't seem like the right way to go.<Adding random features to a language just because they look cool is a terrible thing to do. ----------------------- Rainer Deyke:I want to throw these words back at you, because my first impression of D was "the bastard child of C++ and Java, with a random assortment of new features thrown in without rhyme or reason". D is many things, but a simple and elegant language it is not.<I agree. D is nicer than C++, etc. But it's also complex, unelegant, and sometimes it looks like a "random assortment of new features". D looks like a grown language, not a planned one. Still, I like it enough. ----------------------- Walter Bright:My first years of C++ code also looked a lot like just plain old C (in fact, it arguably still does).<You may look at the source code of some good C++ project. I guess you will not look at the source code of LLVM. ----------------------- Ary Borenszweig:Unfortunately the designers of D doesn't care at all about IDE support for their language,<*All* modern languages are designed to have good interactions with IDEs. So D will eventually need such things. ----------------------- Andrei Alexandrescu:I think D should also visibly obviate some use of Python or Perl for prototyping.<A good language works well with others, like Python, it doesn't try to fully "obviate" them. But I agree that D may grow some features that allow it to "scale down". Syntax support for tuples and list comprehensions are two of the things that can help a lot in such regard. ----------------------- Rainer Deyke:I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'. I *like* having to write 'p->f();' instead of 'p.f();'. It keeps my code clearly and more explicit.<That's noisy and bad looking. In 90-95% of the lines of code you don't need that level of precision. (Generally the point of D is to be simpler than C++, even if this means losing some of of the power of C++). ----------------------- Ary Borenszweig: int property foo(); // getter int property foo(int value); // setter ----------------------- Bye, bearophile (sorry for the late replay, I was away)
Jul 27 2009
bearophile wrote:Michiel Helvensteijn:This was about overloading &&, || and !, right? It's not a random feature. It's a logical consequence of the operator overloading system. Leaving them out is arbitrary. You will never convince me that a potentially useful feature should be left out because it could potentially be abused. By the way, I did think of a compelling use-case just yesterday. Boost has a three-valued bool type. true, false and maybe. Seems pretty logical to overload the boolean operators for it. -- Michiel HelvensteijnI don't know a compelling use-case either. But that doesn't mean there isn't any. Nor are there any real dangers. Arbitrarily restricting the possibilities of D doesn't seem like the right way to go.<Adding random features to a language just because they look cool is a terrible thing to do.
Jul 27 2009
bearophile wrote:Lutger:Yes, but practically every other language implements testing in libraries. My suggestion was not build a big unit testing system in the language, but just to add those one or two changes in order to build such a testing library on top of the existing system. ...It's interesting why unittest (and assert) are such big success. My idea is that it's not in spite of, but because of their utter simplicity. I speculate that if it would have been different, for example if you would had to create a new file for a unittest, it would not have been used so much.<It's another example of scaling. A good unit test system is the one that allows you to write quickly and in a very simple way simple tests. And to use them later to build more and more complex unit testing as the program gets bigger. At the moment D unit testing is fit for small purposes only, but not for the larger ones (Python docstests are fit for even small purposes, you can use it for unit testing even if your program is 15 lines long).Walter Bright:Isn't this a bit contradictory? ...It may indeed be the syntax, but consider that no other language adopted those constructs. There was a proposal to add contracts to C++0x which died. I added them to Digital Mars C++ and nobody cared.<A way to solve this problem is to add features (to D2), and then later remove them (to D3) if they aren't appreciated. This breaks backward compatibility, as D2 does on D1. Or even (silly idea) adding features to D1 may be good to test such features to see if they are worth addign to D2 :-) Using D1 as experimental field... ----------------------- Michiel Helvensteijn:I don't know a compelling use-case either. But that doesn't mean there isn't any. Nor are there any real dangers. Arbitrarily restricting the possibilities of D doesn't seem like the right way to go.<Adding random features to a language just because they look cool is a terrible thing to do.Andrei Alexandrescu:list comprehensions are only worth it if you add tuples imho. Otherwise I think we can get by just fine with map/filter/reduce plus extension methods.I think D should also visibly obviate some use of Python or Perl for prototyping.<A good language works well with others, like Python, it doesn't try to fully "obviate" them. But I agree that D may grow some features that allow it to "scale down". Syntax support for tuples and list comprehensions are two of the things that can help a lot in such regard.
Jul 27 2009
Lutger:Adding random features to a language just because they look cool is a terrible thing to do.Isn't this a bit contradictory?<I don't see a contradiction. For example list comprehensions and unit testing module aren't random features, they are known to be quite useful.list comprehensions are only worth it if you add tuples imho.<Nope. Lazy/eager sequence comprehensions can be useful in many situations even if you don't have tuples.Otherwise I think we can get by just fine with map/filter/reduce plus extension methods.<Reduce is not intuitive. And a sequence comp is shorter and more readable (IF the syntax is really good) than most map/filter/xmap/xfilter. Bye, bearophile
Jul 27 2009
bearophile wrote:Lutger:Sure, I was referring to your suggestion of adding features to see how they pan out and then removing them, not any particular feature.Adding random features to a language just because they look cool is a terrible thing to do.Isn't this a bit contradictory?<I don't see a contradiction. For example list comprehensions and unit testing module aren't random features, they are known to be quite useful.list comprehensions don't do anything useful over map & friends but make them look better. They are super handsome in python in combination with tuples. So my point was, if you go for list comprehensions as a sweetener, you really should have some tuples with them too.list comprehensions are only worth it if you add tuples imho.<Nope. Lazy/eager sequence comprehensions can be useful in many situations even if you don't have tuples.
Jul 27 2009
Lutger:I was referring to your suggestion of adding features to see how they pan out and then removing them, not any particular feature.<Yes, there's a small contradiction there, because usually there's no a single best solution to a problem, and even oppostite strategies may be both useful in different situations. But I was mostly talking about finding a way to play very well with an experimental feature before adding it to the real language.list comprehensions don't do anything useful over map & friends but make them look better.<I don't agree because: - They are indeed syntax sugar, but they allow for shorter, less noisy/cluttered, and more readable code (IF and only if their syntax is really good), this improves code, makes it more readable, avoids errors, etc. - You often don't need delegates, so: (x * x for x in xrange(10, 20) if x & 1) doesn't require the compiler to be able to inline two closures as in: xfilter((int x){ return x & 1; }, xmap((int x){ return x * x; }, xrange(10, 20))) (This is code from my dlibs, and it's not much readable. "xsomething" means it's lazy, as in that Python line of code. Phobos2 usually doesn't need delegates here. Currently DMD and LDC aren't able to inline closures it seems no one is interested in this and I don't know why).They are super handsome in python in combination with tuples.<Tuples are very handy, and I'd like to have a good support for them in D. But note that there are no tuples in that code I have just shown. Bye, bearophile
Jul 27 2009
python: (x * x for x in xrange(10, 20) if x & 1) D as of now: map!("a * a")( filter!("a & 1")( range!(10,20) ) ) D with extension methods: range!(10,20).filter!("a & 1").map!("a * a") Not too bad right? (the range function is fictional, I forgot if and which one exists in phobos)
Jul 27 2009
Lutger:python: (x * x for x in xrange(10, 20) if x & 1) D as of now: map!("a * a")( filter!("a & 1")( range!(10,20) ) ) D with extension methods: range!(10,20).filter!("a & 1").map!("a * a") Not too bad right?It's not terrible, but it's far from being nice. Strings are sharp and rough tools, when used for such purposes. Map and filter of Phobos2 are lazy only, so if you need an array you have to add another function call (that's named array() in my dlibs, I don't remember the Phobos2 name).(the range function is fictional, I forgot if and which one exists in phobos)In Phobos2 it's named iota (from APL, maybe), it doesn't require the exclamation mark (bang, !) (but it's not smart enough yet to accept just one argument, and default the first one to zero). Bye, bearophile
Jul 27 2009
bearophile wrote:Lutger:array. Andreipython: (x * x for x in xrange(10, 20) if x & 1) D as of now: map!("a * a")( filter!("a & 1")( range!(10,20) ) ) D with extension methods: range!(10,20).filter!("a & 1").map!("a * a") Not too bad right?It's not terrible, but it's far from being nice. Strings are sharp and rough tools, when used for such purposes. Map and filter of Phobos2 are lazy only, so if you need an array you have to add another function call (that's named array() in my dlibs, I don't remember the Phobos2 name).
Jul 27 2009
Lutger wrote:python: (x * x for x in xrange(10, 20) if x & 1) D as of now: map!("a * a")( filter!("a & 1")( range!(10,20) ) ) D with extension methods: range!(10,20).filter!("a & 1").map!("a * a") Not too bad right? (the range function is fictional, I forgot if and which one exists in phobos)(It's called iota.) Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Lutger wrote:Oh yes, I remember being freaked out reading about the APL after that one: (~R∊R∘.×R)/R←1↓⍳R (this finds all prime numbers from 1 to R in the APL)python: (x * x for x in xrange(10, 20) if x & 1) D as of now: map!("a * a")( filter!("a & 1")( range!(10,20) ) ) D with extension methods: range!(10,20).filter!("a & 1").map!("a * a") Not too bad right? (the range function is fictional, I forgot if and which one exists in phobos)(It's called iota.) Andrei
Jul 27 2009
Lutger:Oh yes, I remember being freaked out reading about the APL after that one: (~R∊R∘.×R)/R←1↓⍳R (this finds all prime numbers from 1 to R in the APL)I can't read that APL code, and Python code that does the same is more than twice longer (and it may also be slower):[2, 3, 5, 7, 11, 13, 17, 19] Bye, bearophilen = 20 [x for x in xrange(2,n) if all(x % i for i in xrange(2,x))]
Jul 27 2009
Walter Bright Wrote:Your view of the problem is too technical. Functions used to denote arbitrary "actions", while properties are designed to simulate data rather than functions: fields with minor logic concerning accessing them, e.g. input validation. This got reflected in naming conventions directing to name functions with verbs and properties and fields with nouns. Properties being implemented by functions is a technical detail, which may change: the property logic can become declarative or come in a form of type checking and be tested by caller, or most probably it can be replaced by invariant altogether. All these alternative solutions have their certain limitations or advantages, but they effectively do the same thing as "functional" properties without changing their semantics. That's why properties are not functions.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?
Jul 27 2009
Kagamin wrote:Walter Bright Wrote:I so don't get this. Yes, functions are used to denote arbitrary actions. Some of these actions can set and get state. It is convenient to benefit of some syntactic aid for those cases (e.g. make their use look and feel like fields). So far so good. But as long as there is no innate validation or enforcement from the compiler that for example you setFoo(5) ensures that getFoo() will get you 5, we're only talking about syntactic convenience. This is it: syntactic convenience. Nothing else.Your view of the problem is too technical. Functions used to denote arbitrary "actions", while properties are designed to simulate data rather than functions: fields with minor logic concerning accessing them, e.g. input validation.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?This got reflected in naming conventions directing to name functions with verbs and properties and fields with nouns.Fine.Properties being implemented by functions is a technical detail, which may change: the property logic can become declarative or come in a form of type checking and be tested by caller, or most probably it can be replaced by invariant altogether.I don't understand this.All these alternative solutions have their certain limitations or advantages, but they effectively do the same thing as "functional" properties without changing their semantics.And consequently this.That's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before. Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Kagamin wrote:I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that want to implement it in D.Walter Bright Wrote:I so don't get this. Yes, functions are used to denote arbitrary actions. Some of these actions can set and get state. It is convenient to benefit of some syntactic aid for those cases (e.g. make their use look and feel like fields). So far so good. But as long as there is no innate validation or enforcement from the compiler that for example you setFoo(5) ensures that getFoo() will get you 5, we're only talking about syntactic convenience. This is it: syntactic convenience. Nothing else.Your view of the problem is too technical. Functions used to denote arbitrary "actions", while properties are designed to simulate data rather than functions: fields with minor logic concerning accessing them, e.g. input validation.Properties. Your syntactic sugar: int i = c.p; // int i = c.p() p = i // c.p(i) They can't do these things: * No control over their use by class designer: ANY member function with one or zero parameters may be called using 'property syntax'. This is not a good thing.Why not? Seriously, what is the semantic difference?This got reflected in naming conventions directing to name functions with verbs and properties and fields with nouns.Fine.Properties being implemented by functions is a technical detail, which may change: the property logic can become declarative or come in a form of type checking and be tested by caller, or most probably it can be replaced by invariant altogether.I don't understand this.All these alternative solutions have their certain limitations or advantages, but they effectively do the same thing as "functional" properties without changing their semantics.And consequently this.That's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before.
Jul 27 2009
Ary Borenszweig wrote:I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Ary Borenszweig wrote:The ambiguity with a function returning a delegate? The debugger support? Help UI designers with properties windows? If none of those convinced you, ok.I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that would want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Ary Borenszweig wrote:Andrei Alexandrescu wrote:Convince me of what? Of the fact that the current design has problems, absolutely. That we need to embark on all sorts of baroque notations for the sake of a convenience, not quite. AndreiAry Borenszweig wrote:The ambiguity with a function returning a delegate? The debugger support? Help UI designers with properties windows? If none of those convinced you, ok.I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that would want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Ary Borenszweig wrote:I agree. It's very hard to find the correct way to implement it... :(Andrei Alexandrescu wrote:Convince me of what? Of the fact that the current design has problems, absolutely. That we need to embark on all sorts of baroque notations for the sake of a convenience, not quite. AndreiAry Borenszweig wrote:The ambiguity with a function returning a delegate? The debugger support? Help UI designers with properties windows? If none of those convinced you, ok.I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that would want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Ary Borenszweig wrote:Andrei Alexandrescu wrote:Might be because (a) we aren't getting our priorities right, (b) we ascribe more to properties than what the compiler really makes of them. At the end of the day, a property is a notational convenience. Instead of writing: obj.set_xyz(5); int a = obj.get_xyz(); properties allow us to write: obj.xyz = 5; int a = obj.xyz; Just to be 100% clear, I agree that the convenience is great. But I don't know why the hell I need to learn a whole different syntax for *defining* such things, when the compiler itself doesn't give a damn - it just blindly rewrites the latter into something like the former. Now to be 101% clear, I also understand that the current design sucks. But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary. AndreiAry Borenszweig wrote:I agree. It's very hard to find the correct way to implement it... :(Andrei Alexandrescu wrote:Convince me of what? Of the fact that the current design has problems, absolutely. That we need to embark on all sorts of baroque notations for the sake of a convenience, not quite. AndreiAry Borenszweig wrote:The ambiguity with a function returning a delegate? The debugger support? Help UI designers with properties windows? If none of those convinced you, ok.I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that would want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Ary Borenszweig wrote:Again, I agree. I think just a minimal change is required to accomplish that. See my other post: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=93751 (but I think it should be "property int" instead of "int property", because modifiers can't come after the type).Andrei Alexandrescu wrote:Might be because (a) we aren't getting our priorities right, (b) we ascribe more to properties than what the compiler really makes of them. At the end of the day, a property is a notational convenience. Instead of writing: obj.set_xyz(5); int a = obj.get_xyz(); properties allow us to write: obj.xyz = 5; int a = obj.xyz; Just to be 100% clear, I agree that the convenience is great. But I don't know why the hell I need to learn a whole different syntax for *defining* such things, when the compiler itself doesn't give a damn - it just blindly rewrites the latter into something like the former. Now to be 101% clear, I also understand that the current design sucks. But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.Ary Borenszweig wrote:I agree. It's very hard to find the correct way to implement it... :(Andrei Alexandrescu wrote:Convince me of what? Of the fact that the current design has problems, absolutely. That we need to embark on all sorts of baroque notations for the sake of a convenience, not quite. AndreiAry Borenszweig wrote:The ambiguity with a function returning a delegate? The debugger support? Help UI designers with properties windows? If none of those convinced you, ok.I think the only way you and Walter can understand what a property is and what it is used for is to use for some time a language that would want to implement it in D.I totally agree that "that's nice". But it's just notational convenience, and there was no proof aired here to convince me otherwise. Andrei
Jul 27 2009
Andrei Alexandrescu wrote: ...At the end of the day, a property is a notational convenience.That sums up the discussion pretty nicely. Except for one thing: what do you think of the ability of tools ( I include metaprogramming with this ) to recognize properties as such?
Jul 27 2009
Lutger wrote:Andrei Alexandrescu wrote: ...They'd employ whatever means the language has for enabling the notational convenience. AndreiAt the end of the day, a property is a notational convenience.That sums up the discussion pretty nicely. Except for one thing: what do you think of the ability of tools ( I include metaprogramming with this ) to recognize properties as such?
Jul 27 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works. Plus, damn near every other common language out there these days has some form of property syntax (except maybe C++, but that's just a steaming pile anyway, and anyone who can get used to that garbage is going to be among the last people to hit stumbling blocks over a modern property syntax). So prior experience with real property syntax is extremely common. Plus, none of the people using those langauges have had trouble with these property syntaxes anyway. It's a complete non-issue. While we're at it, let's just throw away for and foreach, after all, there can't possibly be any point to those if you already have while! Why should we give people new to D the aggrivation of having to learn for and foreach syntax?
Jul 27 2009
Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com... While we're at it, let's just throw away for and foreach, after all, there can't possibly be any point to those if you already have while! Why should we give people new to D the aggrivation of having to learn for and foreach syntax?Throw while too, we have goto!
Jul 27 2009
Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.Plus, damn near every other common language out there these days has some form of property syntax (except maybe C++, but that's just a steaming pile anyway, and anyone who can get used to that garbage is going to be among the last people to hit stumbling blocks over a modern property syntax). So prior experience with real property syntax is extremely common. Plus, none of the people using those langauges have had trouble with these property syntaxes anyway. It's a complete non-issue.Java too I guess.While we're at it, let's just throw away for and foreach, after all, there can't possibly be any point to those if you already have while! Why should we give people new to D the aggrivation of having to learn for and foreach syntax?Removing foreach would make code more verbose. Adding property crap would make code more verbose. Andrei
Jul 27 2009
Andrei Alexandrescu wrote:Nick Sabalausky wrote:PLUS: * need to remember that get is not followed by () * need to remember that set does not take a type like any other function, just an identifier * need to remember that there is no () after width WHY? Do you have just one reason for which all this is necessary? Andrei"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.
Jul 27 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4l4nr$20u0$4 digitalmars.com...So people are going to automagically just *know* to stick "opGet_" in front of the name to make it a property?Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.PLUS: * need to remember that get is not followed by ()1. That's trivial to remember. 2. Ok, so we can stick a () after get.* need to remember that set does not take a type like any other function, just an identifierset(auto v) Problem solved. Plus with both of the above, you're seem to be using arguments against a specific decicated property syntax as as arguments against dedicated property syntaxes in general.* need to remember that there is no () after widthWhy in the world would there be? It's not a function.
Jul 27 2009
Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4l4nr$20u0$4 digitalmars.com...It's ONE rule to remember, and it blends perfectly with the rest of the language. Compare that with the bunch of arbitrary rules that you propose.So people are going to automagically just *know* to stick "opGet_" in front of the name to make it a property?Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.No. "Trivial to remember" is far from enough. You need to justify why there's anything I need to remember in the first place.PLUS: * need to remember that get is not followed by ()1. That's trivial to remember.2. Ok, so we can stick a () after get.Ok, so it's an arbitrary rule. Why exactly is it necessary?Yah, "solved" with more arbitrary syntax. I love this.* need to remember that set does not take a type like any other function, just an identifierset(auto v) Problem solved.Plus with both of the above, you're seem to be using arguments against a specific decicated property syntax as as arguments against dedicated property syntaxes in general.Well I don't know what it is, so there might as well be some parens in there. It's all arbitrary after all. Syntax upon syntax upon syntax. Why do we need it? This looks like switch all over again :o). Andrei* need to remember that there is no () after widthWhy in the world would there be? It's not a function.
Jul 27 2009
On Mon, Jul 27, 2009 at 3:01 PM, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Nick Sabalausky wrote:Some other things to consider. Here's what Qt's property syntax looks like: Q_PROPERTY( type name READ getFunction [WRITE setFunction] [RESET resetFunction] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] ) So this: Q_PROPERTY( QString Id READ getId WRITE setId ); defines a property named "Id" of type QString which you read with getId() and write with setId(). That's also kinda similar to Python's basic pre-2.4 mechanism (you write normal functions then mark them as part of a property with a separate line of code). The main thing that interests me here is the other stuff in Qt's props: RESET, DESIGNABLE, SCRIPTABLE, and STORED. Why does Qt need these and what does that imply for D? --bb"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4l4nr$20u0$4 digitalmars.com...It's ONE rule to remember, and it blends perfectly with the rest of the language. Compare that with the bunch of arbitrary rules that you propose.So people are going to automagically just *know* to stick "opGet_" in front of the name to make it a property?Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.No. "Trivial to remember" is far from enough. You need to justify why there's anything I need to remember in the first place.PLUS: * need to remember that get is not followed by ()1. That's trivial to remember.2. Ok, so we can stick a () after get.Ok, so it's an arbitrary rule. Why exactly is it necessary?Yah, "solved" with more arbitrary syntax. I love this.* need to remember that set does not take a type like any other function, just an identifierset(auto v) Problem solved.Plus with both of the above, you're seem to be using arguments against a specific decicated property syntax as as arguments against dedicated property syntaxes in general.Well I don't know what it is, so there might as well be some parens in there. It's all arbitrary after all. Syntax upon syntax upon syntax. Why do we need it? This looks like switch all over again :o).* need to remember that there is no () after widthWhy in the world would there be? It's not a function.
Jul 27 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4l83a$27u6$1 digitalmars.com...Well I don't know what it is, so there might as well be some parens in there. It's all arbitrary after all. Syntax upon syntax upon syntax. Why do we need it? This looks like switch all over again :o).Well let's just throw away all our high-level syntax then and go back to machine code.
Jul 27 2009
Andrei Alexandrescu wrote:Nick Sabalausky wrote:Which is why Steven Schveighoffer's is suggestion is the most pragmatic so far. You just add a "property" attribute to a regular function definition. (And it doesn't look ugly, unlike the opGet_/opSet_ idea.)"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.
Jul 27 2009
On Mon, Jul 27, 2009 at 2:24 PM, John C<johnch_atms hotmail.com> wrote:Andrei Alexandrescu wrote:ethod,Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a m=getthey must know how to define a property. None of that property blah { =ey'd... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. Th=oWhich is why Steven Schveighoffer's is suggestion is the most pragmatic s=have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { =A0 =A0get { return _width; } =A0 =A0set(v) { _width =3D v; } } And immediately know exactly how the poroperty syntax works.Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.far. You just add a "property" attribute to a regular function definition=.(And it doesn't look ugly, unlike the opGet_/opSet_ idea.)+1. That's really all that's needed. A simple flag to say "this function acts like a field". The other variants go further and try to get rid of some of the redundancy typical of get/set pairs. But that part isn't really necessary even if it might be convenient. --bb
Jul 27 2009
Bill Baxter wrote:On Mon, Jul 27, 2009 at 2:24 PM, John C<johnch_atms hotmail.com> wrote:Also note that the syntactic sugar could be implemented as library, using macros. Too bad macros were left to D3.0, even though Walter added a "macro" keyword. (Which was also a breaking change to the finalized D1.0, blergh.) That said, it would be really convenient for mixed compile time/runtime meta programming to be able to associate additional information to a attribute syntax for this. This would be useful for reflection, serialization, IDEs, and other modern day crap like this. Additionally, a "readonly" modifier would eliminate lots of uses of properties: often, you just want to make a field not writeable from outside. Normally, you would make the field private, and add a public readonly getter. Note that making the field immutable is not enough, because it can't be written by the class.Andrei Alexandrescu wrote:+1. That's really all that's needed. A simple flag to say "this function acts like a field".Nick Sabalausky wrote:Which is why Steven Schveighoffer's is suggestion is the most pragmatic so far. You just add a "property" attribute to a regular function definition. (And it doesn't look ugly, unlike the opGet_/opSet_ idea.)"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h4kkn3$14pv$1 digitalmars.com...Sure. My point is that with using standard method definition syntax there's no need for even looking over an example.But what I want is to come with a new design that adds minimum aggravation on the learning programmer. If they know how to define a method, they must know how to define a property. None of that property blah { get ... set ... } crap is necessary.I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.
Jul 27 2009
grauzone wrote:That said, it would be really convenient for mixed compile time/runtime meta programming to be able to associate additional information to a attribute syntax for this. This would be useful for reflection, serialization, IDEs, and other modern day crap like this.Oops, "annotations" is the term in use, not "attributes".
Jul 27 2009
"grauzone" <none example.net> wrote in message news:h4lnpn$11h$1 digitalmars.com...grauzone wrote:That said, it would be really convenient for mixed compile time/runtime meta programming to be able to associate additional information to a attribute syntax for this. This would be useful for reflection, serialization, IDEs, and other modern day crap like this.Oops, "annotations" is the term in use, not "attributes".
Jul 27 2009
On Mon, 27 Jul 2009 17:24:06 -0400, John C <johnch_atms hotmail.com> wrote:Which is why Steven Schveighoffer's is suggestion is the most pragmatic so far. You just add a "property" attribute to a regular function definition. (And it doesn't look ugly, unlike the opGet_/opSet_ idea.)I'll note that I wasn't the first to suggest it... But I do think it's the best solution. -Steve
Jul 27 2009
Nick Sabalausky wrote:I can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.I don't know exactly how this is supposed to work. The basic idea is obvious, but: - How does it interact with inheritance? Can I override properties? Can I partially override properties (setter but not getter)? - Can I write a setter that accepts another type? - Can I write a templated setter that accepts *all* types? If so, how? - Can I create a delegate from a setter/getter? If so, how? - I assume that getters/setters can have individual access specifiers (i.e. private/protected/public), but is that really the case? Dedicated property syntax isn't hard to learn, but it's not as obvious as you make it our to be. Note that none of these issues exist with opGet_foo, which follows the same rules as all functions. -- Rainer Deyke - rainerd eldwood.com
Jul 27 2009
Rainer Deyke wrote:Nick Sabalausky wrote:+1 AndreiI can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.I don't know exactly how this is supposed to work. The basic idea is obvious, but: - How does it interact with inheritance? Can I override properties? Can I partially override properties (setter but not getter)? - Can I write a setter that accepts another type? - Can I write a templated setter that accepts *all* types? If so, how? - Can I create a delegate from a setter/getter? If so, how? - I assume that getters/setters can have individual access specifiers (i.e. private/protected/public), but is that really the case? Dedicated property syntax isn't hard to learn, but it's not as obvious as you make it our to be. Note that none of these issues exist with opGet_foo, which follows the same rules as all functions.
Jul 27 2009
Andrei Alexandrescu wrote:Rainer Deyke wrote:makes some things ugly or impossible (like, what if I want a public getter but a protected setter?) I like the mechanics of the opGet_Xxx proposal, but aesthetically, it just makes my eyes bleed (as do the other "op" functions, like opApply, that don't technically overload any "op"erators). For my money, the best solution is a simple "property" keyword as a function modifier. Only functions with the "property" modifier would be allowed to pose as fields (getters called without parens, setters called using assignment syntax). But, in all other respects, they should act just like functions. --benjiNick Sabalausky wrote:+1 AndreiI can't be nice about this: Any programmer who has *any* aggrivation learning any even remotely sane property syntax is an idiot, period. They'd have to be incompetent to not be able to look at an example like this: // Fine, I'll throw DRY away: int _width; int width { get { return _width; } set(v) { _width = v; } } And immediately know exactly how the poroperty syntax works.I don't know exactly how this is supposed to work. The basic idea is obvious, but: - How does it interact with inheritance? Can I override properties? Can I partially override properties (setter but not getter)? - Can I write a setter that accepts another type? - Can I write a templated setter that accepts *all* types? If so, how? - Can I create a delegate from a setter/getter? If so, how? - I assume that getters/setters can have individual access specifiers (i.e. private/protected/public), but is that really the case? Dedicated property syntax isn't hard to learn, but it's not as obvious as you make it our to be. Note that none of these issues exist with opGet_foo, which follows the same rules as all functions.
Jul 27 2009
Benji Smith wrote:For my money, the best solution is a simple "property" keyword as a function modifier. Only functions with the "property" modifier would be allowed to pose as fields (getters called without parens, setters called using assignment syntax). But, in all other respects, they should act just like functions.I like being able to distinguish between the property itself and its setter/getter function. For example, let's say 'y' is a property of 'x'. z = x.y; // Calls the getter. x.y = z; // Calls the setter. z = &x.y; // But what's this? The setter, the getter, or the property itself? That's why I support opSet_foo and opGet_foo (although I'd prefer the simpler get_foo and set_foo). -- Rainer Deyke - rainerd eldwood.com
Jul 27 2009
On Mon, 27 Jul 2009 21:14:10 -0400, Rainer Deyke <rainerd eldwood.com> wrote:Benji Smith wrote:This is a general problem with all overloaded functions. The answer is that it's the first one declared. You can specify it by declaring the type of z before assigning. I think this might need some attention in general, not just for properties. -SteveFor my money, the best solution is a simple "property" keyword as a function modifier. Only functions with the "property" modifier would be allowed to pose as fields (getters called without parens, setters called using assignment syntax). But, in all other respects, they should act just like functions.I like being able to distinguish between the property itself and its setter/getter function. For example, let's say 'y' is a property of 'x'. z = x.y; // Calls the getter. x.y = z; // Calls the setter. z = &x.y; // But what's this? The setter, the getter, or the property itself?
Jul 28 2009
Rainer Deyke wrote:May I remind the group of a possible solution I've offered before? Here it is, slightly modified to go along with the current "no grouping of setters and getters" trend. -------------------------------------------------- class C { int foo.get() { ... } void foo.set(int value) { ... } } C c; c.foo = 5; // c.foo.set(5); i = c.foo; // i = c.foo.get(); d = &c.foo.get; // d = delegate to foo getter -------------------------------------------------- It doesn't make your eyes bleed (I think). And you have a way to distinguish between getter, setter and property. The downside for D is that get() and set() may overshadow member functions of the property type. In my own language, this is not an issue, since get() and set() are special functions that have the same meaning for each type. And overriding them is just what a property is supposed to do. -- Michiel HelvensteijnFor my money, the best solution is a simple "property" keyword as a function modifier. Only functions with the "property" modifier would be allowed to pose as fields (getters called without parens, setters called using assignment syntax). But, in all other respects, they should act just like functions.I like being able to distinguish between the property itself and its setter/getter function.
Jul 28 2009
Rainer Deyke wrote:Benji Smith wrote:class X { int _y; property pure const int y() { return _y; } property void y(int y_) { _y = y_; } pure const int y(int i, int j) { return _y+i*j; } }; auto x = new X; int delegate() z_getter = &x.y; void delegate(int) z_setter = &x.y; int delegate(int,int) z_irrelevant = &x.y; int* z_variable = &x._y; // What do you mean by "the property itself"? there's no single address to such thing. z_setter(16); assert(z_getter() == 16); assert(z_irrelevant(3,4) == 28); assert(*z_variable == 16);For my money, the best solution is a simple "property" keyword as a function modifier. Only functions with the "property" modifier would be allowed to pose as fields (getters called without parens, setters called using assignment syntax). But, in all other respects, they should act just like functions.I like being able to distinguish between the property itself and its setter/getter function. For example, let's say 'y' is a property of 'x'. z = x.y; // Calls the getter. x.y = z; // Calls the setter. z = &x.y; // But what's this? The setter, the getter, or the property itself?That's why I support opSet_foo and opGet_foo (although I'd prefer the simpler get_foo and set_foo).
Jul 28 2009
- How does it interact with inheritance? Can I override properties?sureCan I partially override properties (setter but not getter)?- Can I write a setter that accepts another type?no- Can I write a templated setter that accepts *all* types? If so, how?wut?- Can I create a delegate from a setter/getter? If so, how?eh. Like events?- I assume that getters/setters can have individual access specifierssure(i.e. private/protected/public), but is that really the case?sure ------------------- property -> prop (it appears billions of times) ------------------- How about big letters? string Name(){} void Name(string) {} void doStuff(string) {} ------------------- 1. To show up differently from the normal methods in the reflection to be used by the IDE. 2. To behave like fields with respect to +=, and other stuff. Number (1) is the only thing that Delphi does, it does not have operator overloading like (2). The D compiler does not need any distinction between the normal methods, and the "ones" to be shown in the IDE because it does not create the reflection information, (to be used by the IDE) ------------------- Constraints on properties, but NOT relevant (skip this text) 1. No multiple parameters void setPosition(double, double) {} 2. No overloads void setPosition( Vec2 ) {} void setPosition( Point2 ) {} The IDE could pick the ones that have minimum a getter, hence not relevant. (I think) virtual setPosition() virtual getPosition() public override double Area { get {return mySide * mySide;} } 4. Not same name as methods. 5. ... working on this one... D style properties are less restrictive. -------------------- Java Annotations provide a more GENERAL way to "tag" methods, by providing user defined Annotations. (Heavily used in EJB 3.0) Prop public String name() {} The API provides routines like .getAnnotations() .isAnnotationPresent() Again D does not create the reflection information to be used by the IDE. -------------------- (skip the following text) Chocomilk is very good, I drink it every morning. I don't know why? I just like it. Also I just don't understand those coffee people. How can they drink that discusting juice every day, make jokes about it every morning? No for me a nice cup of warm chocolate milk.
Jul 27 2009
sclytrack wrote:How about identifiers starting with ß? _?- How does it interact with inheritance? Can I override properties?sureCan I partially override properties (setter but not getter)?- Can I write a setter that accepts another type?no- Can I write a templated setter that accepts *all* types? If so, how?wut?- Can I create a delegate from a setter/getter? If so, how?eh. Like events?- I assume that getters/setters can have individual access specifierssure(i.e. private/protected/public), but is that really the case?sure ------------------- property -> prop (it appears billions of times) ------------------- How about big letters?string Name(){} void Name(string) {} void doStuff(string) {} ------------------- 1. To show up differently from the normal methods in the reflection to be used by the IDE. 2. To behave like fields with respect to +=, and other stuff. Number (1) is the only thing that Delphi does, it does not have operator overloading like (2). The D compiler does not need any distinction between the normal methods, and the "ones" to be shown in the IDE because it does not create the reflection information, (to be used by the IDE) ------------------- Constraints on properties, but NOT relevant (skip this text) 1. No multiple parameters void setPosition(double, double) {} 2. No overloads void setPosition( Vec2 ) {} void setPosition( Point2 ) {} The IDE could pick the ones that have minimum a getter, hence not relevant. (I think) virtual setPosition() virtual getPosition() public override double Area { get {return mySide * mySide;} } 4. Not same name as methods. 5. ... working on this one... D style properties are less restrictive. -------------------- Java Annotations provide a more GENERAL way to "tag" methods, by providing user defined Annotations. (Heavily used in EJB 3.0) Prop public String name() {} The API provides routines like .getAnnotations() .isAnnotationPresent() Again D does not create the reflection information to be used by the IDE. -------------------- (skip the following text) Chocomilk is very good, I drink it every morning. I don't know why? I just like it. Also I just don't understand those coffee people. How can they drink that discusting juice every day, make jokes about it every morning? No for me a nice cup of warm chocolate milk.
Jul 28 2009
On Mon, 27 Jul 2009 10:54:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Let me bring you back to the issue at hand: writefln = "hi"; :) properties are *implemented* using functions, but both properties and function usage should be restricted to disallow bizare code. Another example: I've brought up this example before, but I'll summarize the issue. I created a TimeSpan struct for Tango, which represents a span of time. I had static functions to create time spans, and properties to convert time spans. For example: struct TimeSpan { static TimeSpan seconds(long n); // returns a TimeSpan representing n seconds ... long seconds(); // convert this timespan to seconds } So you use it like this: auto ts = TimeSpan.seconds(5); assert ts.seconds == 5; But then I got a bug report one day that this assert fails: auto ts = TimeSpan.seconds(5); ts.seconds = 4; assert(ts.seconds == 4); What the second line does is create a temporary TimeSpan of 4 seconds, and throw it away. What happened here? Why did the compiler compile this code at all? Well, because I can't tell the compiler "no, that static seconds function is *not* a property", someone tried to use it as one, and then complained it didn't work like it should. Would anyone reading the second line of code, knowing it compiles, *not* think "aha! TimeSpan has a way to set it's seconds component"? The "solution" was to rename the static function to fromSeconds, although this is still valid code: ts.fromSeconds = 4; it doesn't look like it means anything (what's this fromSeconds field?). But WTF? Why do I have to do this kind of shit instead of just telling the compiler "this is how you use my object. Any other uses are invalid. End of discussion". For reference: http://www.dsource.org/projects/tango/ticket/1184 -SteveThat's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before.
Jul 27 2009
Steven Schveighoffer wrote:On Mon, 27 Jul 2009 10:54:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:That wart must be eliminated. But the shortcomings of the current design are not a proof that we need a specialized facility for what is at the end of the day nothing but a notational convenience.Let me bring you back to the issue at hand: writefln = "hi"; :)That's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before.properties are *implemented* using functions, but both properties and function usage should be restricted to disallow bizare code.I agree.Another example: I've brought up this example before, but I'll summarize the issue. I created a TimeSpan struct for Tango, which represents a span of time. I had static functions to create time spans, and properties to convert time spans. For example: struct TimeSpan { static TimeSpan seconds(long n); // returns a TimeSpan representing n seconds ... long seconds(); // convert this timespan to seconds } So you use it like this: auto ts = TimeSpan.seconds(5); assert ts.seconds == 5; But then I got a bug report one day that this assert fails: auto ts = TimeSpan.seconds(5); ts.seconds = 4; assert(ts.seconds == 4); What the second line does is create a temporary TimeSpan of 4 seconds, and throw it away. What happened here? Why did the compiler compile this code at all? Well, because I can't tell the compiler "no, that static seconds function is *not* a property", someone tried to use it as one, and then complained it didn't work like it should. Would anyone reading the second line of code, knowing it compiles, *not* think "aha! TimeSpan has a way to set it's seconds component"? The "solution" was to rename the static function to fromSeconds, although this is still valid code: ts.fromSeconds = 4; it doesn't look like it means anything (what's this fromSeconds field?). But WTF? Why do I have to do this kind of shit instead of just telling the compiler "this is how you use my object. Any other uses are invalid. End of discussion". For reference: http://www.dsource.org/projects/tango/ticket/1184I agree that that's a wart too that needs to be removed. Andrei
Jul 27 2009
On Mon, 27 Jul 2009 12:16:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:I personally am OK with any solution that allows me to specify that a function is actually a property, thereby restricting the compiler from allowing assignment calls with normal functions. The most straightforward solution I can think of is marking a function with a keyword, i.e.: property int x() {return _x;} property void x(int n) {_x = n;} The other syntax suggestions provide different added bonuses, but I think all of those bonuses are not as critical as code working as expected. For example: - implied hidden storage - documenting property getters/setters as one entity - being able to execute a getter during a debug session. -SteveOn Mon, 27 Jul 2009 10:54:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:That wart must be eliminated. But the shortcomings of the current design are not a proof that we need a specialized facility for what is at the end of the day nothing but a notational convenience.Let me bring you back to the issue at hand: writefln = "hi"; :)That's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before.
Jul 27 2009
Steven Schveighoffer Wrote:On Mon, 27 Jul 2009 12:16:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Agreed. And enabling the function pair to be enclosed in a block would reduce repitition a tad as well as indicate they are one entity. property { int x() { return _x; } void x(int n) { _x = n; } }Steven Schveighoffer wrote:I personally am OK with any solution that allows me to specify that a function is actually a property, thereby restricting the compiler from allowing assignment calls with normal functions. The most straightforward solution I can think of is marking a function with a keyword, i.e.: property int x() {return _x;} property void x(int n) {_x = n;}On Mon, 27 Jul 2009 10:54:00 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:That wart must be eliminated. But the shortcomings of the current design are not a proof that we need a specialized facility for what is at the end of the day nothing but a notational convenience.Let me bring you back to the issue at hand: writefln = "hi"; :)That's why properties are not functions.This post had a negative effect on me: I now think properties are functions even more than before.The other syntax suggestions provide different added bonuses, but I think all of those bonuses are not as critical as code working as expected. For example: - implied hidden storage - documenting property getters/setters as one entity - being able to execute a getter during a debug session. -Steve
Jul 27 2009
Andrei Alexandrescu Wrote:Might be because (a) we aren't getting our priorities right, (b) we ascribe more to properties than what the compiler really makes of them. At the end of the day, a property is a notational convenience. Instead of writing: obj.set_xyz(5); int a = obj.get_xyz(); properties allow us to write: obj.xyz = 5; int a = obj.xyz; Just to be 100% clear, I agree that the convenience is great. But I don't know why the hell I need to learn a whole different syntax for *defining* such things, when the compiler itself doesn't give a damn - it just blindly rewrites the latter into something like the former.May be namespace states your complaints. It doesn't add a whole new syntax, only kinda one extra level of indirection, naturally reusing existing feature of operator overloading, and I think it should look natural to compiler too: it's the same as operator overloading, compiler already does it. And calling properties is only one aspect of the problem. The other is declaration. You heard it: implicit backing storage, default trivial implementation, type consistency. We don't have problems with calling properties. In fact complaints about current design originates from problems with property declaration: the problem is compiler doesn't know what is a function and what is a property.
Jul 28 2009