digitalmars.D - Does D have too many features?
- Walter Bright (5/5) Apr 28 2012 Andrei and I had a fun discussion last night about this question. The id...
- deadalnix (6/12) Apr 28 2012 I think many D features come from the lack of AOP in D. I already
- Timon Gehr (3/17) Apr 28 2012 Many times, actually. But you have *never* sketched how support for AOP
- deadalnix (5/21) Apr 28 2012 Off topic. I discussed several proposals, and I invest time ever since
- Jacob Carlborg (4/8) Apr 29 2012 This would be awesome to have.
- Nick Sabalausky (8/13) Apr 28 2012 Off the top of my head:
- SomeDude (12/16) Apr 28 2012 Version could be replaced with "static if", but I like them, it
- q66 (9/28) Apr 28 2012 There are minimalistic languages that don't add too much
- SomeDude (21/30) Apr 28 2012 I appreciate minimalistic languages. I love the simplicity of
- q66 (7/41) Apr 28 2012 This kind of attitude "we need big fat bullshit like Java and
- SomeDude (9/15) Apr 28 2012 Python has two big drawbacks for large projects:
- H. S. Teoh (45/63) Apr 28 2012 Who says D doesn't have duck-typing?
- Nick Sabalausky (6/26) Apr 28 2012 Yea, templated code is structurally-typed (duck-typed) by default. Not a...
- Jonas Drewsen (6/23) Apr 29 2012 Go is a static duck typed language (when using interfaces anyway)
- David Nadlinger (5/7) Apr 29 2012 Regardless of the fact that I tend to agree with you on this one,
- SomeDude (7/14) Apr 29 2012 Well yes and no. It's the difference between "I think that", and
- SomeDude (5/12) Apr 28 2012 BTW, look at Scala for another language that's designed for large
- Paulo Pinto (10/55) Apr 28 2012 Python is my favorite scripting language, but I would never propose a
- H. S. Teoh (20/26) Apr 29 2012 [...]
- Paulo Pinto (13/16) Apr 29 2012 Suffice to say, that on that specific project we had weeks without
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/62) Apr 29 2012 Wait, dynamic-language programmers use CI?
- Dmitry Olshansky (32/38) Apr 28 2012 1. Drop is(...) feature entirely. Extend __traits where needed and move
- Timon Gehr (9/25) Apr 28 2012 static is not accessible at compile time, would you want to change that?
- Dmitry Olshansky (12/42) Apr 28 2012 Oops, scratch that comment about static/immutable.
- Timon Gehr (30/60) Apr 28 2012 That would work in certain cases, where the initializer is not a single
- Nick Sabalausky (16/52) Apr 28 2012 Those are good. They are essentially enumerations.
- Timon Gehr (15/66) Apr 29 2012 enum{
- Nick Sabalausky (19/26) Apr 29 2012 No, they're not. Non-anon enums *contain* a bunch of manifest constants....
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (18/41) Apr 30 2012 I see that way as well. I have a section titled "enum values that are
- H. S. Teoh (27/38) Apr 29 2012 [...]
- David Nadlinger (7/9) Apr 29 2012 To be fair, the template matching logic in D is quite complicated
- Timon Gehr (36/74) Apr 29 2012 I think it is never valid.
- jerro (2/5) Apr 28 2012 But enums aren't only used for optimization. What if you want to
- Robert Clipsham (11/15) Apr 29 2012 My primary use case for the with() statement is with final switch:
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/16) Apr 29 2012 Hah, clever! Never would've thought of that.
- Jacob Carlborg (4/16) Apr 30 2012 That's the only thing I used the with-statement for.
- simendsjo (4/23) Apr 30 2012 I use it to "fake" object initializers from C#:
- John Chapman (2/5) Apr 30 2012 Ooh, nice - care to share?
- simendsjo (6/12) Apr 30 2012 Basically just
- Manu (2/24) Apr 30 2012 That's the only thing I was aware it did ;) .. are there other uses?
- Jacob Carlborg (16/19) Apr 30 2012 You can use it to access members without a receiver as well:
- q66 (16/22) Apr 28 2012 - AAs integrated in the language; you barely ever use AA literals
- Nick Sabalausky (3/9) Apr 28 2012 That's just craziness!
- Timon Gehr (2/12) Apr 28 2012 +1.
- Marco Leise (7/18) Apr 28 2012 Madness even! AAs are soon mostly in the library and that's a good trade...
- Nick Sabalausky (7/10) Apr 28 2012 Yea, it's a tradeoff either way. Once we have a mature "D CPAN", there w...
- SomeDude (5/30) Apr 29 2012 I don't want AA to be removed from the core language. That would
- Nick Sabalausky (6/22) Apr 29 2012 There will still be sugar in the compiler so they appear to be builtins....
- Nick Sabalausky (3/27) Apr 29 2012 In fact, don't regular arrays already work like this?
- SomeDude (11/18) Apr 29 2012 Hmmm, sounds nice, but bolting the language with the standard
- Timon Gehr (2/12) Apr 29 2012 druntime is the library it will be moved into, not Phobos.
- SomeDude (2/3) Apr 29 2012 Ah, that's ok, then.
- H. S. Teoh (11/22) Apr 29 2012 [...]
- SomeDude (2/17) Apr 28 2012 I disagree with every single point here.
- q66 (5/24) Apr 28 2012 So you don't agree version() is horribly half assed without
- SomeDude (9/15) Apr 28 2012 Sorry, with that, I agree. Nick Sabalausky proposed to remove
- H. S. Teoh (9/26) Apr 28 2012 But if you're gonna do that, might as well just fold the feature into
- SomeDude (7/35) Apr 28 2012 I really don't care how it's implemented or what its syntax is.
- Nick Sabalausky (6/22) Apr 28 2012 FWIW, one of the big wins I see in migrating "version" to "static if" is...
- SomeDude (6/32) Apr 29 2012 I don't mind changing the semantics of "version", but replacing
- H. S. Teoh (26/38) Apr 28 2012 On the contrary, AA's are a major reason I started programming in D. In
- q66 (16/74) Apr 28 2012 Too large collection becomes too hard to manage. Separating it
- SomeDude (9/25) Apr 28 2012 Yeah, but core language AA are so useful it would be a MAJOR
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/29) Apr 29 2012 Let's get a standard package manager that we either advocate on
- SomeDude (15/18) Apr 29 2012 Don't get me wrong. I don't want to reduce the amount of modules
- Manu (5/18) Apr 29 2012 or include in the releases before we start talking about reducing the
- Jacob Carlborg (7/14) Apr 30 2012 I'm working on this. Unfortunately I cannot work on this full-time so
- simendsjo (10/24) Apr 30 2012 =
- Jacob Carlborg (8/14) Apr 30 2012 "This project is currently on ice in favor of porting orbit from D1 to
- Timon Gehr (36/94) Apr 28 2012 This sounds reasonable.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (13/117) Apr 29 2012 Nope.
- Andrej Mitrovic (3/8) Apr 29 2012 It's great to see another (successful) language implemented this. Do
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/14) Apr 29 2012 AFAIK no.
- Jesse Phillips (4/17) Apr 29 2012 I believe DIP 4 is the proposal
- Andrej Mitrovic (6/9) Apr 29 2012 Well it says they're both superseeded by DIP 6 but DIP6 didn't
- Jacob Carlborg (5/15) Apr 30 2012 I think someone started to work on this. I have no idea what happened to...
- Timon Gehr (7/27) Apr 29 2012 I didn't say this was how it worked in the current compiler
- Mike Parker (3/12) Apr 28 2012 Someone forgot to tell me how unusable they are, because I've been using...
- Era Scarecrow (15/23) Apr 28 2012 And the STL and libc isn't big? Size is only intimidating if you
- Jacob Carlborg (4/26) Apr 29 2012 As others have said, I think this is crazy.
- Andrej Mitrovic (24/25) Apr 28 2012 I don't mind extra features, just as long as they're properly
- Walter Bright (5/7) Apr 28 2012 A mixin template is instantiated in context of the instantiation point, ...
- Andrej Mitrovic (2/6) Apr 28 2012 Ooooh. Suddenly that explains some of my compilation errors.
- Timon Gehr (17/25) Apr 28 2012 The implementation seems to disagree:
- Walter Bright (3/30) Apr 30 2012 The behavior is as I described.
- David Nadlinger (4/10) Apr 30 2012 Why not just require mixin templates to be declared using »mixin
- Artur Skawina (8/15) Apr 28 2012 Yeah, but this was actually the only suggestion so far in this thread th...
- Simen Kjaeraas (10/29) Apr 29 2012 At least some of us want mixin templates to be marked mixin at declarati...
- Artur Skawina (15/47) Apr 29 2012 Yes, that's the other possible use for marking a template as a mixin. Un...
- Jacob Carlborg (7/24) Apr 29 2012 If a anonymous classes where remove from D, life would get even harder
- H. S. Teoh (14/22) Apr 29 2012 [...]
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (6/31) Apr 29 2012 I use them too. They're useful if you have an abstract method that just
- foobar (20/26) Apr 28 2012 D has a lot of ad-hock features which make the language
- Timon Gehr (10/40) Apr 28 2012 That would be opApply.
- foobar (32/84) Apr 28 2012 I have used D and didn't claim that foreach isn't useful.
- SomeDude (14/117) Apr 28 2012 Well, it's your opinion. But I bet it's not the opinion of
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/123) Apr 29 2012 --
- David Nadlinger (6/10) Apr 29 2012 This is off-topic, but in general, please try to quote only the
- Era Scarecrow (12/33) Apr 28 2012 Aren't both of those just side effects of bad design? Most
- Dmitry Olshansky (10/35) Apr 28 2012 C++ was criticized for a long time for NOT having foreach in the
- Era Scarecrow (14/25) Apr 28 2012 If it simplifies code, makes it easier, and is more consistent,
- SomeDude (30/56) Apr 29 2012 One of the ideas that I see regularly thrown around is to remove
- Timon Gehr (15/100) Apr 29 2012 Well, I don't think this is better than built-in foreach (with full
- foobar (23/70) Apr 29 2012 I think we reached a matter of taste here. How often do you use
- Timon Gehr (21/94) Apr 29 2012 Not too often, but it is awesome that it actually works. ;)
- foobar (37/164) Apr 29 2012 I agree and indeed I haven't argued to remove break/continue from
- Timon Gehr (7/40) Apr 29 2012 The filter condition is not always conveniently expressed in terms of a
- H. S. Teoh (8/19) Apr 29 2012 Like if the Ackermann function was evaluated in CTFE for very large
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (7/97) Apr 29 2012 Yeah, we tried that in C++. It sucked.
- foobar (15/50) Apr 30 2012 Meta comment: C++ is the spawn of the devil so I don't accept
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (19/63) Apr 30 2012 Of course it can, but not with type inference, unless you templatize it....
- Timon Gehr (4/44) Apr 30 2012 I agree. It is due to the fact that currently actually no inference
- Jacob Carlborg (7/11) Apr 29 2012 Have a look at what Scala have done. They basically have the complete
- Timon Gehr (3/13) Apr 29 2012 It is not as powerful as what we have in D and it requires invoking the
- Jacob Carlborg (5/20) Apr 29 2012 That's the whole point, there won't be any special case for CTFE. BTW,
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/51) Apr 29 2012 That is absolutely horrible. It's not how branches are meant to be used.
- H. S. Teoh (33/53) Apr 28 2012 I disagree. Having a dedicated foreach construct allows the compiler to
- foobar (18/80) Apr 28 2012 compiler inlining?
- Era Scarecrow (14/26) Apr 28 2012 Mmm well the main reason I see using .di files, is cases when
- foobar (5/32) Apr 29 2012 floppies, are you for real?!
- Era Scarecrow (5/9) Apr 29 2012 What? I like my floppies... or did when they worked.
- Adam Wilson (13/64) Apr 28 2012 I have written code that will do just that. You can check it out here:
- Jacob Carlborg (6/18) Apr 29 2012 I agree with this one as well. At least if the compiler would be
- akaz (2/6) Apr 29 2012 I strongly support this.
- bearophile (54/58) Apr 28 2012 Finding things to remove now from D is hard, in my code I have
- Walter Bright (2/3) Apr 28 2012 As opposed to Phobos being phat?
- q66 (5/8) Apr 28 2012 Well my concern is so that it doesn't end up like Python standard
- H. S. Teoh (36/46) Apr 28 2012 On the contrary, being able to do stuff without having to reinvent the
- q66 (5/81) Apr 28 2012 Well I'm not obviously saying the features should disappear, what
- H. S. Teoh (18/22) Apr 28 2012 If you're talking about very specific, niche features (like parsing
- Era Scarecrow (19/40) Apr 28 2012 OMG I love you :)
- Jonathan M Davis (9/14) Apr 28 2012 If the changes to ref and const ref that were discussed during the beta ...
- bearophile (8/11) Apr 28 2012 A more general answer. From my experience the real problem with
- David Piepgrass (45/65) Jul 10 2012 forum.dlang.org apparently failed to post this 10 minutes ago,
- Timon Gehr (27/33) Apr 28 2012 - Associative array literals as non-associative array initializers [1]
- Timon Gehr (3/19) Apr 28 2012 Oh, completely forgot about that one:
- H. S. Teoh (7/32) Apr 28 2012 Yeah that one elicited a WAT from me when I first started using it.
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/34) Apr 29 2012 How so? It's seemed entirely reasonable to me.
- H. S. Teoh (10/19) Apr 29 2012 [...]
- Jonathan M Davis (7/10) Apr 28 2012 Really? I use that all the time with AAs. Without that, you would have t...
- bearophile (18/23) Apr 28 2012 LDC1 compiler introduced a small optimization, it looks for
- Jonathan M Davis (12/29) Apr 28 2012 I really don't see anything "unclean" about returing a pointer. It does ...
- David Nadlinger (6/8) Apr 29 2012 Huh? I can't think of a situation where a hash table lookup would
- Jonathan M Davis (29/38) Apr 29 2012 If you have something like
- David Nadlinger (3/13) Apr 29 2012 Yes, point taken, but what does this have to do with locality?
- Jonathan M Davis (11/24) Apr 29 2012 I think that you're thinking of something completely different about th=
- David Nadlinger (4/15) Apr 29 2012 Okay, then it was just a misunderstanding, I thought about memory
- Timon Gehr (6/44) Apr 29 2012 Well, what if the programmer "knows" that foo does not change 'aa', but
- Jonathan M Davis (6/11) Apr 29 2012 It's exactly as safe as any iterator or range which could be invalidated...
- H. S. Teoh (8/21) Apr 29 2012 [...]
- Timon Gehr (3/22) Apr 30 2012 The AA might actually contain the provided default value, so 'get' is
- Andrej Mitrovic (14/15) Apr 28 2012 AFAIK this is a property of how the opIn_r function is implemented,
- Timon Gehr (3/18) Apr 29 2012 I know, but 'in' is somewhat of a misnomer. Anyway, it is not a huge iss...
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/20) Apr 29 2012 I hate to nitpick and all that, but opBinaryRight!"in" actually works
- Andrej Mitrovic (25/27) Apr 29 2012 Yes and then you get to have those nice template instantiation errors,
- Andrej Mitrovic (11/14) Apr 29 2012 Sorry that's wrong, should be:
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/19) Apr 29 2012 I think all of the error messages you posted could need improvement. In
- H. S. Teoh (17/24) Apr 28 2012 Comma operator.
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (12/33) Apr 29 2012 +1.
- H. S. Teoh (11/20) Apr 29 2012 [...]
- bearophile (4/9) Apr 30 2012 What ambiguities?
- H. S. Teoh (29/36) Apr 30 2012 [...]
- simendsjo (18/52) Apr 30 2012 I think struct literals is worse in this regard:
- foobar (11/27) Apr 30 2012 Structs provide POD value types and as such MUST include the
- bearophile (6/8) Apr 30 2012 Named arguments help avoid some bugs, make the code more
- bearophile (6/20) Apr 30 2012 That code doesn't compile:
- H. S. Teoh (9/34) Apr 30 2012 [...]
- bearophile (4/7) Apr 30 2012 How? (I think you are wrong again).
- H. S. Teoh (29/36) Apr 30 2012 [...]
- bearophile (7/14) Apr 30 2012 But it's a kind of safe breaking, it doesn't cause a lot of
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (7/41) Apr 30 2012 You always risk breaking *something* when you change an interface,
- Timon Gehr (9/43) Apr 30 2012 No it does not. Changing an interface is bound to break code.
- Timon Gehr (2/25) Apr 30 2012 You probably should try compiling that code. ;)
- Andrej Mitrovic (9/11) Apr 29 2012 It probably will. Quote Andrei: "Yah, we should add that at some
- Jacob Carlborg (4/6) Apr 30 2012 `` is better because you don't have to escape ".
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/9) Apr 30 2012 That only applies when you actually have " in the string. I think both
- Jacob Carlborg (4/14) Apr 30 2012 When is r"" a better use than ``? We already have the regular "".
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/19) Apr 30 2012 You don't have escape sequences inside r"", so they can be useful if you...
- Jacob Carlborg (5/10) May 01 2012 `` can be used for that. ` is good because it's a different delimiter
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/14) May 01 2012 It *can*, but it's annoying on non-US keyboards, which was my original
- Jacob Carlborg (4/6) May 01 2012 Well, I don't agree.
- Maxim Fomin (33/39) Apr 28 2012 I guess the underlying problem is inability to formulate the
- D Day (1/45) Apr 28 2012
- SomeDude (22/66) Apr 28 2012 That's a very well worded post. That's one more reason why the
- Adam D. Ruppe (19/20) Apr 28 2012 I think most the responses to this thread are insane.
- Jonathan M Davis (4/8) Apr 28 2012 LOL. Yeah. Many of them involve completely gutted pieces of the language...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (11/31) Apr 29 2012 OK, so while in general I agree that 'new' shouldn't be tied to the GC
- Peter Alexander (14/20) Apr 28 2012 Here's my list:
- H. S. Teoh (28/37) Apr 28 2012 On the contrary, it's a major helper for writing generic code. In my new
- Peter Alexander (22/51) Apr 28 2012 The problem there is that toHash is a member function. That UFCS
- bearophile (20/29) Apr 28 2012 I used to think the same. But Haskell offers "." and $ to chain
- Peter Alexander (21/37) Apr 28 2012 What D does and what Haskell does are very different things. D
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/48) Apr 29 2012 In my experience, pure is only hard to use in D due to the runtime and
- SomeDude (17/25) Apr 29 2012 Maybe you don't feel the benefit because you have less bugs in
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (9/44) Apr 29 2012 I don't know of any production compilers that make significant use of
- Manu (5/26) Apr 28 2012 I disagree with every one of those points, except maybe 'shared', which
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (8/34) Apr 29 2012 For shared to be useful, every function you call on/with a shared
- Timon Gehr (15/35) Apr 28 2012 - UFCS:
- Peter Alexander (12/32) Apr 28 2012 Exactly. The problem is having multiple function invocation
- q66 (2/34) Apr 28 2012
- F i L (22/32) Apr 28 2012 It can be very useful for jQuery/JSON style dynamic objects:
- Peter Alexander (11/45) Apr 28 2012 This is a perfect example of misuse.
- SomeDude (5/9) Apr 28 2012 So basically, for your very specific issue, you want to ditch a
- Jonathan M Davis (12/29) Apr 28 2012 For better or worse, the solution for smart pointers in D would be to us...
- Dmitry Olshansky (5/34) Apr 28 2012 *cough* alias this *cough*
- Jonathan M Davis (18/23) Apr 28 2012 That's not necessarily a good idea, depending on how it's used. You want...
- Dmitry Olshansky (7/29) Apr 29 2012 So you just need not to have any _member_ functions on smart pointer?
- Jonathan M Davis (5/18) Apr 29 2012 That could work (though they'd obviously have to be in the same module a...
- F i L (16/70) Apr 28 2012 It's not abuse, it's design. That's why I called the type
- F i L (1/1) Apr 28 2012 Typos. Typos everywhere :S I'm sure you get my meaning.
- Nick Sabalausky (10/20) Apr 29 2012 [...]
- Jacob Carlborg (4/15) Apr 29 2012 I love all these features beside the attributes.
- deadalnix (10/16) Apr 28 2012 OK longer answer.
- SomeDude (4/8) Apr 28 2012 What happens the day the language is actually fit for embedded
- H. S. Teoh (7/16) Apr 28 2012 We need to fix things so that using a single feature in Phobos will not
- SomeDude (16/27) Apr 28 2012 It is, but it's actually a very difficult implementation issue.
- H. S. Teoh (17/25) Apr 28 2012 As I said in another thread, the _functionality_ of various is()
- deadalnix (5/23) Apr 28 2012 version(foobar) returning a boolean at compile time for instance.
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (5/28) Apr 29 2012 Let's not forget .reverse. Why these are properties (and .dup/.idup) is
- deadalnix (2/44) Apr 29 2012 Why they are not provided as lib but by the core language ?
- H. S. Teoh (9/14) Apr 29 2012 [...]
- Nick Sabalausky (12/14) Apr 29 2012 You can overload on out parameters. You can't overload on return type. S...
- deadalnix (6/17) Apr 29 2012 Good point, but it have many way to work around and shouldn't justify a
- H. S. Teoh (15/17) Apr 29 2012 I argue that using 'out' vs. a pointer is a good thing, because it
- SomeDude (16/40) Apr 30 2012 Of course, a better way would be to change the meaning of the
- deadalnix (3/37) Apr 30 2012 It isn't a good idea.
- Nick Sabalausky (6/8) Apr 30 2012 void foo()
- SomeDude (2/11) Apr 30 2012 OKay, I meant in the function signatures
- deadalnix (8/23) Apr 30 2012 I do agree. However, I don't think this apply in any way to our case.
- foobar (10/32) Apr 30 2012 Well the functional way would be to use Option types as in:
- deadalnix (6/12) Apr 28 2012 Ho god D is HUGE !
- F i L (82/88) Apr 28 2012 First, I completely agree with some points already made here, and
- Manu (3/90) Apr 28 2012 Hear hear.
- Francois Chabot (11/15) Apr 28 2012 To me, properties are much more than a convenience. The important
- Jacob Carlborg (75/90) Apr 29 2012 In principle I agree with you. But in practice this doesn't always work....
- Andrej Mitrovic (20/26) Apr 29 2012 This is a great point and an issue I've ran into and talked about
- H. S. Teoh (10/28) Apr 29 2012 [...]
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/30) Apr 29 2012 What you just talked about = semantics. So, it is a language issue.
- Nick Sabalausky (9/11) Apr 29 2012 We sort of do:
- bearophile (5/6) Apr 29 2012 It doesn't work outside functions. More info:
- Manu (23/28) Apr 28 2012 I personally find the wealth of features in D to be one of it's major
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/34) Apr 29 2012 --
- Jonathan M Davis (3/4) Apr 28 2012 It did, but it won't. It's either already been deprecated or will be soo...
- Jonathan M Davis (82/89) Apr 28 2012 Well, that's a hard one. There isn't much in the language that I'd remov...
- bearophile (23/45) Apr 28 2012 retro() can't replace foreach_reverse until the front-end
- Era Scarecrow (46/55) Apr 28 2012 I have one source file called staticdata.d; Here immutable
- Jonathan M Davis (12/27) Apr 28 2012 I know that you find easier to read. A number of people do. But it is ju...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/33) Apr 29 2012 I've done ML, F#, Erlang, Haskell, Lisp, and others, and I still don't
- Dmitry Olshansky (10/27) Apr 28 2012 bleh C++ doesn't have reverse loop in the language. all there is
- H. S. Teoh (29/36) Apr 29 2012 [...]
- deadalnix (3/36) Apr 30 2012 It is an implementation issue (a real and serious one, but still). It
- David Nadlinger (28/33) Apr 29 2012 Slightly related: For this:
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/46) Apr 29 2012 Amen.
- deadalnix (3/11) Apr 29 2012 This is an implementation issue and shouldn't be an argument for
- Peter Alexander (3/19) Apr 29 2012 The 'sufficiently smart compiler' argument is old and invalid.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/23) Apr 29 2012 Indeed; at some point, you have to admit that implementation will have
- Dmitry Olshansky (6/24) Apr 30 2012 Right, nowdays any compiler is either smart enough or a dead meat that
- SomeDude (3/7) Apr 30 2012 A smart enough compiler would understand natural language and
- Dmitry Olshansky (6/14) Apr 30 2012 Yeah, unless it decides to take a vacation. :)
- deadalnix (7/25) Apr 30 2012 This is a case by case issue. You should consider fixing implementation
- H. S. Teoh (25/36) Apr 29 2012 [...]
- Timon Gehr (2/37) Apr 30 2012
- akaz (4/8) May 03 2012 There is no tool (maybe the compiler could provide such a tool)
- ponce (10/11) Apr 28 2012 - builtin complex types (I don't _need_ be able to write "4 + 5i")
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (14/25) Apr 29 2012 +1, and .reverse. I'm also against .dup and .idup being properties, but
- bearophile (4/6) Apr 29 2012 Sometimes I use std.exception.enforce(), that uses lazy.
- Jesse Phillips (4/8) Apr 30 2012 Complexity of the operation. in on an array is not nearly the
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/12) Apr 30 2012 I know, but it's very intuitive still; see Python.
- SomeDude (13/19) Apr 30 2012 And that's why it's somewhat dangerous. Because it's so easy to
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/23) May 01 2012 1) So because some people might use a feature incorrectly due to lack of...
- SomeDude (10/13) May 01 2012 It's not crippling the language. Nothing prevents you from
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (12/24) May 01 2012 No, it is not an O(1) operation, it is *close* to O(1) (as much sense as...
- Tobias Pankrath (7/18) May 02 2012 +1
- Andrei Alexandrescu (4/21) May 02 2012 The problem here is making complexity an implementation detail of a
- Timon Gehr (13/37) May 02 2012 The interface is different:
- Andrei Alexandrescu (4/16) May 02 2012 The syntactic interface is the same. That would be the semantic
- Timon Gehr (5/24) May 02 2012 Encapsulation of complexity is a problem if it is not obvious to the
- so (11/25) May 01 2012 I remember this was the argument Andrei also came up. Still can't
- Jonathan M Davis (13/15) May 01 2012 If in is not restricted to a particular level Big-O complexity, then you...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (29/44) May 01 2012 I don't think 'in' is actually used in any generic code (other than code...
- H. S. Teoh (48/95) Apr 28 2012 Ugh. C++ multiple inheritance is a labyrinth, nay, a veritable minefield
- bearophile (13/20) Apr 28 2012 Walter accepted to deprecate it lot of time ago, but it's not
- Jonathan M Davis (14/23) Apr 28 2012 You don't have to. If you have
- Era Scarecrow (15/21) Apr 28 2012 Depends on how many levels you are using on a array. I've noted
- Andrej Mitrovic (5/16) Apr 28 2012 That's not really the benefit of those initializers. This is:
- Francois Chabot (14/15) Apr 28 2012 - The is expressions are confusing as hell, and it seems to me
- Paulo Pinto (38/44) Apr 28 2012 - two different ways of creating function pointers is confusing
- Timon Gehr (10/46) Apr 29 2012 'delegate' is more powerful, 'function' is more efficient. If you don't
- Paulo Pinto (18/56) Apr 29 2012 That is what I mean. The compiler could make the distinction between
- David Nadlinger (8/11) Apr 29 2012 How would this work? Function pointers are only a single word in
- Paulo Pinto (3/14) Apr 29 2012 Yes, that is what I had in mind. That is what is done in .NET as far as
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (6/52) Apr 29 2012 D unit tests were never really useful for anything beyond single-library...
- bearophile (6/10) Apr 29 2012 I think D has to offers means to library writers to instrument
- SomeDude (4/10) Apr 29 2012 What's the problem ? What prevents you to put the unit tests in
- deadalnix (2/5) Apr 29 2012 +1 A good std.unittest + attributes is probably a better approach.
- H. S. Teoh (16/23) Apr 29 2012 The only reason I actually write unittests for D code is because
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (23/44) Apr 29 2012 The problem with D's unit test support is that it doesn't integrate well...
- H. S. Teoh (16/45) Apr 29 2012 [...]
- Jonathan M Davis (11/14) Apr 29 2012 It wouldn't make sense. It's nowhere near as bad as C++, but dmd has to
- Timon Gehr (10/28) Apr 30 2012 Only the symbols that need to be analysed actually get analysed (eg.
- Andrej Mitrovic (15/19) Apr 29 2012 For RDMD you can do:
- SomeDude (11/35) Apr 30 2012 OK, that makes sense. What a test framework could do, although
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/39) Apr 30 2012 I don't have a clone of my repo from where I am now, so I can't count,
- SomeDude (3/7) Apr 30 2012 For how many files/lines of code ?
- SomeDude (3/11) Apr 30 2012 And on what hardware ? I'd like to have a bit of an idea of how
- Iain Buclaw (14/27) Apr 30 2012 That sort of speed difference sounds about right. I'm not sure how
- Jacob Carlborg (4/9) Apr 30 2012 DMD calls GCC which calls LD. Unless your using the -lib flag.
- Iain Buclaw (14/39) Apr 30 2012 Having said that, I did produce a report from GDC once with a list of
- SomeDude (2/16) Apr 30 2012 Thx, that's interesting.
- Andrej Mitrovic (8/10) Apr 30 2012 Personally my gripe with compilation times is that I get very used to
- SomeDude (7/21) Apr 30 2012 Yeah, templates is what slows everything down. I'd be very wary
- SomeDude (3/5) Apr 30 2012 Also, in D, bugs in the CTFE slows everything down, in particular
- Andrej Mitrovic (25/28) May 08 2012 Also since 2.059 error reporting is *completely* broken. I have to
- Don Clugston (7/35) May 08 2012 That bug was fixed in git not long after release. Unfortunately it seems...
- Andrej Mitrovic (4/5) May 08 2012 I still get it with this version:
- Don Clugston (3/8) May 09 2012 OK, looks like it's a different bug. Please put in bugzilla, with status...
- Andrej Mitrovic (5/7) May 11 2012 It turns out it's not a regression:
- Andrej Mitrovic (3/7) May 11 2012 In my project making sure my main.d file is compiled *last* reduces
- Jacob Carlborg (3/51) Apr 30 2012 --
- deadalnix (7/27) Apr 30 2012 Agreed.
- Jonathan M Davis (40/62) Apr 29 2012 he
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (11/52) Apr 29 2012 Except we can't do:
- Jonathan M Davis (16/27) Apr 29 2012 What would that buy you? That's what unittest blocks are for. Yes, gett=
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/24) Apr 29 2012 See my other reply to H. S. Teoh for why I'm not a fan of unittest block...
- Tove (12/18) Apr 29 2012 garbage collector
- David Nadlinger (53/54) Apr 29 2012 My personal list of features I could easily live without – some
- Timon Gehr (5/18) Apr 29 2012 Lack of string interpolation is not a reason to kill the token string,
- Adam D. Ruppe (14/17) Apr 29 2012 I never used these until very recently. A couple weeks
- Andrej Mitrovic (13/26) Apr 29 2012 IIRC I think the reason for this might be that some keyboards don't
- bearophile (7/13) Apr 29 2012 I have asked for it, but currently there are no plans in
- Andrej Mitrovic (4/7) Apr 29 2012 Well I assumed they're on the way to deprecation when I've read this:
- David Nadlinger (14/19) Apr 29 2012 What I forgot to mention:
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/24) Apr 29 2012 Something like that seems reasonable. At any rate, version in its
- SomeDude (3/10) Apr 29 2012 It sounds indeed nice, but I prefer convention over
- David Nadlinger (6/16) Apr 29 2012 What exactly does this have to do with »convention over
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (21/71) Apr 29 2012 I use them. They can be useful when you're writing more object-oriented
- Timon Gehr (6/24) Apr 29 2012 Just cast it away if you do eg. locking. There is nothing wrong with it.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (9/40) Apr 29 2012 Sorry, I managed to get myself confused here. What I meant to say was
- jerro (12/15) Apr 29 2012 It does arithmetic shift if the left operand is signed,
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (7/22) Apr 30 2012 The documentation disagrees:
- Timon Gehr (2/27) Apr 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8007
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/35) Apr 30 2012 Thanks; these kinds of documentation bugs can cause really nasty
- Timon Gehr (6/40) Apr 30 2012 I don't trust the documentation. In my experience, it is usually best to...
- H. S. Teoh (36/59) Apr 29 2012 +1. The voice of reason.
- David Nadlinger (12/29) Apr 29 2012 This moves the _implementation_ to druntime, but there is still
- H. S. Teoh (40/66) Apr 29 2012 [...]
- Dmitry Olshansky (11/74) Apr 30 2012 *cough* initializer lists *cough*
- H. S. Teoh (21/47) Apr 30 2012 [...]
- Andrej Mitrovic (2/10) Apr 30 2012 But you can already use this syntax right now?
- bearophile (5/7) Apr 30 2012 But there is a syntax problem:
- H. S. Teoh (6/20) Apr 30 2012 Yes I know you can, it was more of using this syntax for user-defined
- Dmitry Olshansky (6/23) Apr 30 2012 Yes I tried to point out that this also makes this code straight
- Walter Bright (6/8) Apr 30 2012 I don't like them, either, but they were put in at the recommendation of...
- Jacob Carlborg (45/51) Apr 29 2012 * Some of the built-in properties could probably be move to a library
- Dmitry Olshansky (6/13) Apr 29 2012 warning(1): Smalltalk detected! [use -foop-only to ignore]
- David Nadlinger (3/9) Apr 29 2012 We'd still need a solution for continue and break, though.
- Jacob Carlborg (5/16) Apr 29 2012 This has already been solved when using opApply, although quite an ugly
- David Nadlinger (8/19) Apr 29 2012 Yes, but that requires the compiler to generate the return value
- Jacob Carlborg (14/20) Apr 29 2012 Yeah, that would need to be solved. In Ruby it works like this:
- Era Scarecrow (6/16) Apr 29 2012 A thought coming to mind regarding this, is a special exception.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/21) Apr 29 2012 And forced EH which is unacceptable in e.g. a kernel.
- H. S. Teoh (64/78) Apr 29 2012 [...]
- deadalnix (2/77) Apr 30 2012 This make sense. This seems to me like the way to go.
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (8/60) Apr 29 2012 It is very useful in some cases where you operate a lot on the same obje...
- H. S. Teoh (93/109) Apr 29 2012 OK, that got me all riled up about looping constructs, and now I'm
- Don Clugston (9/21) Apr 30 2012 I grepped through the DMD source once, looking for how often Walter uses...
- bearophile (23/26) Apr 30 2012 In my code I use one do-while about every 20 or 30 loops, so they
- Dmitry Olshansky (5/26) Apr 30 2012 You'd love PL/SQL. :)
- Jacob Carlborg (6/14) Apr 30 2012 Yes, a language would basically need to be designed with this in mind
- Timon Gehr (14/55) Apr 30 2012 do{
- Don (7/13) Apr 29 2012 * The >>> operator, which does nothing except introduce bugs (It does
- David Nadlinger (3/5) Apr 29 2012 +1, forgot to mention that one.
- SomeDude (2/7) Apr 29 2012 What's wrong with packages ?
- David Nadlinger (4/5) Apr 29 2012 Nothing – this is about the »package« protection level, not
- SomeDude (3/8) Apr 29 2012 Ah ok. But I'm not sure what's wrong with the package protection
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/14) Apr 29 2012 Yes, me neither. And I have found many cases in my code where using it
- David Nadlinger (6/12) Apr 29 2012 See the Java discussion on »superpackages« – quite often, you
- bearophile (6/9) Apr 29 2012 Weren't Java designers thinking about adding superpackages too to
- Manu (10/24) Apr 29 2012 What does it do? I use this all over the place, I assumed it worked...
- Timon Gehr (5/25) Apr 29 2012 It does work, but it behaves in unexpected ways for narrow signed
- Paulo Pinto (18/25) Apr 29 2012 I've always assume that package is similar to what is available in
- Robert Clipsham (6/7) Apr 29 2012 http://dlang.org/phobos/std_traits#packageName
- Jacob Carlborg (24/27) Apr 29 2012 As far as I know it works like this:
- Don Clugston (4/20) Apr 30 2012 It works only for two types: int and long.
- Manu (6/36) Apr 30 2012 O_O
- Don Clugston (14/44) Apr 30 2012 It's not a bug, it's a design flaw. The buggy behaviour is explicitly
- ponce (3/11) May 01 2012 Thanks for pointing that out.
- Timon Gehr (6/7) May 01 2012 In what way is it safer?
- Jonathan M Davis (5/7) Apr 29 2012 Really? In some cases, it's indispensable. For instance, once std.dateti...
- Kapps (11/22) Apr 29 2012 It's entirely dependent on your coding style. For example, when
- Jonathan M Davis (20/46) Apr 29 2012 It's a question of how inter-dependent your modules are (which is partly...
- deadalnix (3/23) Apr 30 2012 Phobos is a really good example. Modules tend to become more and more
- David Nadlinger (4/6) Apr 30 2012 Except that it doesn't work if the module you want to refactor
- David Nadlinger (21/31) Apr 29 2012 But what happens if std.datetime grows so large that you want to
- Jonathan M Davis (12/47) Apr 29 2012 I'm not claiming that package solves all such issues (and you do give s=
- Paulo Pinto (10/41) Apr 30 2012 I don't see export as nonsense. :)
- bearophile (8/9) Apr 29 2012 This thread now has something like 240 answers (and probably few
- Jonathan M Davis (14/22) Apr 29 2012 Honestly, I don't think that you _can_ take much from this thread other ...
- Dmitry Olshansky (4/26) Apr 30 2012 --
- SomeDude (11/32) Apr 30 2012 These are the only two I can count that nobody felt eager to
- bearophile (11/13) Apr 30 2012 I don't agree, I see some recurring patterns.
- Jonathan M Davis (15/29) Apr 30 2012 I never claimed that I _was_ Walter. I was pointing out that there's ver...
- Walter Bright (22/35) Apr 30 2012 There is less agreement than I thought there would be.
- Adam D. Ruppe (4/5) Apr 30 2012 opApply is great. I find myself finding new, kinda
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/49) Apr 30 2012 I think what we need is an article on ranges on dlang.org (I can't find
- SomeDude (6/11) Apr 30 2012 There is one talk by Andrei
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/16) Apr 30 2012 Right, but we can't expect people who want to learn the language and its...
- SomeDude (7/27) Apr 30 2012 I've put these links in the Wiki. They may not be visible enough,
- Timon Gehr (4/8) Apr 30 2012 foreach has been mentioned. I don't think ranges are unequivocally a
- SomeDude (6/19) Apr 30 2012 Yes, I feel they are complementary. Ranges are cool for
- Steven Schveighoffer (15/19) Apr 30 2012 I think we've already covered this -- opApply does things that ranges
- Walter Bright (2/4) Apr 30 2012 deprecating opApply would require addressing this.
- bearophile (15/22) Apr 30 2012 But you need to keep into account that D2 is still a not widely
- Timon Gehr (3/11) Apr 30 2012 D2 -> D3 will be full of breaking changes anyway. Otherwise there is no
- Andrej Mitrovic (2/3) Apr 30 2012 Uhmm I hope not, otherwise D3 will be dead in the water.
- Timon Gehr (3/7) Apr 30 2012 Just provide an automatic D2->D3 conversion facility.
- Andrej Mitrovic (4/10) Apr 30 2012 An incremental improvement with as little code breakage as possible?
- Timon Gehr (6/17) Apr 30 2012 IMHO that is similar to aiming for some code breakage with as little
- Jonathan M Davis (7/19) Apr 30 2012 But you could do that without creating a D3. Once the implemnetation has...
- bearophile (6/8) Apr 30 2012 I remember Walter (and Andrei) stated that D2 is the latest major
- Don Clugston (3/16) May 03 2012 What is this D3 thing ????
- Jonathan M Davis (24/26) May 03 2012 I think that what it comes down to is that there are a variety of people...
- Era Scarecrow (14/60) May 03 2012 If anything, I would consider D3 an ideal, something to work
- H. S. Teoh (9/21) May 03 2012 Do we know (roughly) how many D users are out there right now?
- Era Scarecrow (10/15) May 03 2012 Don't know. Need a poll :) I'm definitely sure we have at least
- H. S. Teoh (16/27) May 03 2012 Only 10?? Judging from mailing list membership, I'd say at least 25 or
- Era Scarecrow (2/11) May 03 2012 I was being sarcastic :P
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (7/32) May 03 2012 There are more users than one might think. If you fancy some IRC, you
- Jacob Carlborg (7/33) May 04 2012 People has been talking about D3 for quite a while. Have a look at:
- Jonathan M Davis (8/45) May 04 2012 Oh. I know that they've been talking about it for a while, but as far as...
- bearophile (5/6) Apr 30 2012 I think the evolution and updating patterns of the language Scale
- foobar (6/10) Apr 30 2012 Both internal and external iteration have their pros and cons. It
- Kapps (23/27) Apr 30 2012 I practically never use ranges, and instead use opApply for all
- akaz (52/52) Apr 30 2012 Sorry for my 2nd intervention on this thread. I recently ported
- bearophile (19/27) Apr 30 2012 I think D is not C++ done right any more, it's a new language.
- Timon Gehr (25/32) Apr 30 2012 OTOH, this seems to be an exaggeration.
- bearophile (13/22) Apr 30 2012 Someone in Bugzilla ha just proposed an alternative idea, that
- H. S. Teoh (12/26) Apr 30 2012 [...]
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/22) Apr 30 2012 Tell me about it... I've had a few WTF and WAT moments due to D's design...
- Artur Skawina (5/27) May 01 2012 Since one of the most characteristic D features is overloading "static"
- Jacob Carlborg (6/10) May 01 2012 Meaning this would need to be allowed:
- Era Scarecrow (12/14) Apr 30 2012 I can only offer my own experiences. When I first saw D1 and saw
- Simen Kjaeraas (8/26) Apr 30 2012 While I can agree it's not perfect, I have a hard time seeing a better
- Timon Gehr (23/50) Apr 30 2012 Yes they do. (If you are willing to have both kinds of symbols around.)
- bearophile (11/14) Apr 30 2012 Not following the common naming conventions of a language is bad,
- H. S. Teoh (21/27) Apr 30 2012 [...]
- Era Scarecrow (10/19) Apr 30 2012 Then perhaps the comma operator can be pushed to the
- H. S. Teoh (9/25) Apr 30 2012 Actually it's only inside for. A comma in foreach is not a comma
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/27) Apr 30 2012 Indeed. C# just special-cases it inside for.
- SomeDude (8/18) Apr 30 2012 What we need is a "style guide", ala Scott Meyer, i.e try to find
- Andrei Alexandrescu (19/29) May 01 2012 It's a bit inappropriate to bind Walter to such a social contract upon
- Adam D. Ruppe (15/17) May 01 2012 I could live without that one, because D has an alternative:
- Jakob Ovrum (5/23) May 01 2012 S(...) does not exhibit the same problem as {...} exactly because
- Andrei Alexandrescu (4/7) May 02 2012 Good observation. So indeed the { ... } case is inferior because there's...
- Maxim Fomin (4/10) May 01 2012 It has the same problem as the first one: members are part of the
- Jonathan M Davis (11/25) May 01 2012 Yes, members are part of the interface, but if {1, 2} isn't legal, then ...
- Andrei Alexandrescu (3/19) May 02 2012 Well, so probably we shouldn't remove that feature either :o).
- Andrej Mitrovic (3/7) May 01 2012 But not this, right:
- SomeDude (7/16) May 01 2012 Yes, these are named parameters.
- bearophile (24/37) May 02 2012 Those comments weren't required, but they improve the quality of
- Andrei Alexandrescu (5/10) May 02 2012 Sorry, here I meant "agreement" in the statistical sense, i.e. there's
- Paulo Pinto (20/21) Apr 30 2012 I would say many of the discussion items are to be fixed in a D version...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/14) Apr 30 2012 I think the one thing there is universal agreement on is that the comma
- H. S. Teoh (7/19) Apr 30 2012 [...]
- H. S. Teoh (8/13) Apr 30 2012 [...]
- Adam D. Ruppe (2/4) Apr 30 2012 I kinda like having it....
- Maxim Fomin (3/7) Apr 30 2012 I too and I am afraid that disallowing it would result that
- Peter Alexander (3/6) Apr 30 2012 Very few want it, but as a practicality, it would be unwise to
- deadalnix (6/11) Apr 30 2012 Some have proposed that comma operator could create tuples. If void
- Timon Gehr (4/15) Apr 30 2012 I think I use it about every 60 lines of code. Also, I don't think it
- Timon Gehr (2/22) Apr 30 2012
- David Nadlinger (3/10) Apr 30 2012 Care to show some examples?
- H. S. Teoh (10/16) Apr 30 2012 [...]
- bearophile (5/8) Apr 30 2012 Commas do cause some bugs, so maybe they are worth restricting
- deadalnix (4/12) Apr 30 2012 +1
- David Nadlinger (4/7) Apr 30 2012 Also consider that at least on many European keyboard layouts,
- Jonathan M Davis (15/43) Apr 29 2012 Well, it's both really. If the language spec was exact enough, it would ...
- Jacob Carlborg (5/13) Apr 30 2012 I would rather have @property on instance variables be a syntax sugar
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/21) Apr 30 2012 Then there better be a way to mark them final too. ;)
- Jacob Carlborg (5/11) Apr 30 2012 Then what's the point of having a method? Just use a public instance
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/15) Apr 30 2012 Encapsulation. I want contracts in my properties.
- Jacob Carlborg (4/20) May 01 2012 Aha, didn't thin of that. Sure, why not.
- Jonathan M Davis (4/26) Apr 29 2012 Yes, but that still compiles everything. It just gives you a convenient ...
- Walter Bright (2/7) Apr 30 2012 This certainly seems to have become the biggest thread ever!
- Ary Manzana (1/12) Apr 30 2012
- Eyyub (3/15) Apr 30 2012 Yes, this is a very interesting discussion, even for a n00b like
- SomeDude (20/21) Apr 30 2012 What did you expect, really ? That people would say "nothing, the
- deadalnix (4/8) Apr 30 2012 I wouldn't say supporter, but some people think it doesn't worth the
- Timon Gehr (2/10) Apr 30 2012 call by name is useful.
- Don Clugston (22/28) May 03 2012 Other ones which were agreed to a long time ago were:
- Andrei Alexandrescu (8/20) May 03 2012 Good ones. In fact I even discounted them from this discussion because
- Don Clugston (5/27) May 03 2012 Well, they are also used in druntime, in core.stdc.math
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (8/38) May 03 2012 But not quite everything yet. When I tried to pure/nothrow/@safe-ify
- Sean Kelly (9/21) May 03 2012 std.math[special], I eventually stumbled upon code that used =
- Sean Kelly (8/23) May 03 2012 seems to be growing -- people are adding more things to it.
- Don (8/25) May 03 2012 Yes, but why do we have it? We're not C.
- Sean Kelly (12/34) May 03 2012 mention
- deadalnix (2/26) May 03 2012 So they probably belongs to deimos.
- Sean Kelly (11/40) May 03 2012 eems to be growing -- people are adding more things to it.
- deadalnix (3/34) May 06 2012 I may scare people here, but as Deimos is only declaration, I see no
- Walter Bright (2/4) May 06 2012 I do, because it adds another dependency on something not in the main do...
- Jonathan M Davis (9/35) May 03 2012 In principle, having prototypes for the entire standard C library in dru...
- Walter Bright (7/11) May 03 2012 It's there simply because all the Standard C headers should be represent...
- foobar (11/20) May 06 2012 This argument comes up every once in a while even though AFAIK it
- Jonathan M Davis (18/38) May 06 2012 Then you misunderstand. One of the tenets that D holds to is that any C/...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (24/62) May 06 2012 So basically, language design advances on our front have to be hindered
- Jonathan M Davis (62/115) May 06 2012 t
- Jacob Carlborg (4/10) May 07 2012 I had some problems with floats being default initialized to NaN.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/17) May 07 2012 I still think floats being initialized to NaN is an atrocity...
- Andrew Wiley (6/19) May 07 2012 That's still correct behavior for C, actually. Using an uninitialized
- Jeff Nowakowski (3/10) May 07 2012 For variables with static storage, C initializes them by default to
- Jacob Carlborg (6/11) May 07 2012 I've created bindings for libclang, I did that by copy-pasting the C
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/14) May 07 2012 But declarations are very different from actual statements and
- Jacob Carlborg (4/6) May 07 2012 That's true. Yes, declarations.
- foobar (19/58) May 08 2012 I have a three main problems with the above:
- Andrej Mitrovic (3/5) May 08 2012 Yeah there's a nice list in the C++ standard, Annex C.1 (C++ and ISO
- bearophile (10/19) May 08 2012 For various reasons I have translated many times routines,
- Chris Cain (9/11) May 08 2012 I tend to agree with the performance aspect. I just got done with
- foobar (14/34) May 08 2012 That does not contradict what I said. No one stops you from
- Lars T. Kyllingstad (6/8) May 08 2012 No, FORTRAN has absolutely nothing to do with D. C, on the other
- foobar (4/12) May 08 2012 Irrelevant. For all I care druntime could be implemented in
- Lars T. Kyllingstad (5/20) May 08 2012 Um... so you don't mind the C/POSIX declarations being there, you
- foobar (10/31) May 08 2012 Yes, pretty much.
- foobar (10/45) May 08 2012 BTW, it makes sense even if druntime is implemented with C/POSIX
- Sean Kelly (17/37) May 08 2012 hand, does. Both druntime and Phobos depend heavily on the C stdlib. =
- Sean Kelly (9/16) May 08 2012 hand, does. Both druntime and Phobos depend heavily on the C stdlib. =
- foobar (5/24) May 08 2012 Having an internal package is a good idea. Don did the same for
- Jonathan M Davis (19/33) May 08 2012 We've previously discussed having _all_ of the C system call functions f...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/39) May 08 2012 I do think we could benefit from hiding the (deprecated) std.c.* modules...
- Sean Kelly (27/46) May 08 2012 think that=20
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (6/28) May 09 2012 I just hope none of it goes away. I make extensive use of many core.*
- foobar (18/36) May 09 2012 Could you please provide more details about your use-cases?
- Don Clugston (2/54) May 09 2012 There are plenty of systems that don't support C99 perfectly.
- deadalnix (5/61) May 08 2012 I think that goal is misunderstood. It is aimed at human being, not
- foobar (15/20) May 08 2012 Unfortunately that is not the case.
- Sean Cavanaugh (4/14) May 08 2012 Thousands of my C/C++ floating point constants are broken by the CTFE
- Jens Mueller (7/24) May 09 2012 I wholeheartedly agree that breaking changes are frustrating. But
- Jacob Carlborg (4/7) May 09 2012 I don't see any point in supporting 31.f as a floating point syntax.
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (4/9) May 11 2012 +1.
- Sean Cavanaugh (2/17) May 08 2012 s/CTFE/UFCS
- Sean Cavanaugh (2/17) May 08 2012 s/CTFE/UFCS
- Lars T. Kyllingstad (6/15) May 08 2012 I agree that this is a good enough reason in itself. On top of
- Iain Buclaw (7/41) May 03 2012 I used core.stdc.math to map GCC builtins to math lib functions. This
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/45) May 03 2012 Does that play nice with errno?
- Iain Buclaw (10/66) May 04 2012 e
Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?
Apr 28 2012
Le 28/04/2012 20:47, Walter Bright a écrit :Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I think many D features come from the lack of AOP in D. I already mentioned that in some other thread. I would also mention the is expression which does way too many stuffs and many of them are not usefull or counter intuitive and may be replaced by lib support in std.traits .
Apr 28 2012
On 04/28/2012 09:11 PM, deadalnix wrote:Le 28/04/2012 20:47, Walter Bright a écrit :Many times, actually. But you have *never* sketched how support for AOP would look like.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I think many D features come from the lack of AOP in D. I already mentioned that in some other thread.I would also mention the is expression which does way too many stuffs and many of them are not usefull or counter intuitive and may be replaced by lib support in std.traits .
Apr 28 2012
Le 28/04/2012 22:25, Timon Gehr a écrit :On 04/28/2012 09:11 PM, deadalnix wrote:Off topic. I discussed several proposals, and I invest time ever since to come up with a good solution. Introducing a whole new paradigm in a language isn't something light. AST manipulation at compile time is the key.Le 28/04/2012 20:47, Walter Bright a écrit :Many times, actually. But you have *never* sketched how support for AOP would look like.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I think many D features come from the lack of AOP in D. I already mentioned that in some other thread.
Apr 28 2012
On 2012-04-29 00:02, deadalnix wrote:Off topic. I discussed several proposals, and I invest time ever since to come up with a good solution. Introducing a whole new paradigm in a language isn't something light. AST manipulation at compile time is the key.This would be awesome to have. -- /Jacob Carlborg
Apr 29 2012
"Walter Bright" <newshound2 digitalmars.com> wrote in message news:jnhe1i$2vcm$1 digitalmars.com...Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Off the top of my head: - Using function stubs so the implementation can be provided in a separate source and linked in. (Outside of .di files anyway.) - Comma operator - Version blocks: They should be replaced with something that utilizes "static if".
Apr 28 2012
On Saturday, 28 April 2012 at 19:21:51 UTC, Nick Sabalausky wrote:"Walter Bright" <newshound2 digitalmars.com> wrote in message - Version blocks: They should be replaced with something that utilizes "static if".Version could be replaced with "static if", but I like them, it makes code more readable, so I don't think they should go. We don't want to have a "static if hell", where templating code is mixed with version configuration. I think the version keyword is very good. I think instead of thinking about removing features, the more important thing is polishing the existing ones so that they work properly. D is a big language because it tries to span a broad range of uses. Removing complexity from the core language often means adding complexity in the user code, and that's what we don't want.
Apr 28 2012
On Saturday, 28 April 2012 at 20:05:30 UTC, SomeDude wrote:On Saturday, 28 April 2012 at 19:21:51 UTC, Nick Sabalausky wrote:There are minimalistic languages that don't add too much complexity, instead it results in code being kept simple. D needs to do something it does really well and concentrate on that. Otherwise the language will remain being rather vague and doing "a bit of everything, but nothing truly well". Instead of adding more and more features into a rigid language, it needs to be made more flexible and extensible, both syntactically and semantically."Walter Bright" <newshound2 digitalmars.com> wrote in message - Version blocks: They should be replaced with something that utilizes "static if".Version could be replaced with "static if", but I like them, it makes code more readable, so I don't think they should go. We don't want to have a "static if hell", where templating code is mixed with version configuration. I think the version keyword is very good. I think instead of thinking about removing features, the more important thing is polishing the existing ones so that they work properly. D is a big language because it tries to span a broad range of uses. Removing complexity from the core language often means adding complexity in the user code, and that's what we don't want.
Apr 28 2012
On Saturday, 28 April 2012 at 20:09:50 UTC, q66 wrote:On Saturday, 28 April 2012 at 20:05:30 UTC, SomeDude wrote: There are minimalistic languages that don't add too much complexity, instead it results in code being kept simple.I appreciate minimalistic languages. I love the simplicity of Scheme and the design of Lua. Lua and Python are extensible language, but truth be told, they cannot handle large scale programming. In fact, I don't know of any minimalistic language that can scale from hundreds of thousands to millions of lines of code. When you reach these sizes, their simple design becomes a drawback. You start missing lots of features. When you reach large scale programming, you want really powerful tools. That's basically what the Java designers discovered after experience. The original language was simple and easy, but that simplicity translated into way too much boilerplate code. So they kept adding features from version to version, generics, then annotations, a means to create new keywords. And now they would like to add delegates. These are all needed in large programs.D needs to do something it does really well and concentrate on that. Otherwise the language will remain being rather vague and doing "a bit of everything, but nothing truly well".It does a lot of things well already. Our point of comparison Ocaml, i.e languages that are designed to develop large systems. But most of all it needs to stabilize and polish, not change all the time. I think its feature set is very good already. We are far from having explored all its possibilities.Instead of adding more and more features into a rigid language, it needs to be made more flexible and extensible, both syntactically and semantically.
Apr 28 2012
On Saturday, 28 April 2012 at 20:35:40 UTC, SomeDude wrote:On Saturday, 28 April 2012 at 20:09:50 UTC, q66 wrote:This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.On Saturday, 28 April 2012 at 20:05:30 UTC, SomeDude wrote: There are minimalistic languages that don't add too much complexity, instead it results in code being kept simple.I appreciate minimalistic languages. I love the simplicity of Scheme and the design of Lua. Lua and Python are extensible language, but truth be told, they cannot handle large scale programming. In fact, I don't know of any minimalistic language that can scale from hundreds of thousands to millions of lines of code. When you reach these sizes, their simple design becomes a drawback. You start missing lots of features. When you reach large scale programming, you want really powerful tools. That's basically what the Java designers discovered after experience. The original language was simple and easy, but that simplicity translated into way too much boilerplate code. So they kept adding features from version to version, generics, then annotations, a means to create new keywords. And now they would like to add delegates. These are all needed in large programs.D needs to do something it does really well and concentrate on that. Otherwise the language will remain being rather vague and doing "a bit of everything, but nothing truly well".It does a lot of things well already. Our point of comparison Ocaml, i.e languages that are designed to develop large systems. But most of all it needs to stabilize and polish, not change all the time. I think its feature set is very good already. We are far from having explored all its possibilities.Instead of adding more and more features into a rigid language, it needs to be made more flexible and extensible, both syntactically and semantically.
Apr 28 2012
On Saturday, 28 April 2012 at 20:59:48 UTC, q66 wrote:This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.Python has two big drawbacks for large projects: - it's too slow - it's a dynamically-typed language The fact that it's flexible is because it uses duck typing, and AFAIK you can't do duck typing in a statically typed language. So it's cool for small programs, but it can't handle large ones because it's not statically typed. And this opinion doesn't come just out of thin air, I speak from my own professional experience.
Apr 28 2012
On Sat, Apr 28, 2012 at 11:12:38PM +0200, SomeDude wrote:On Saturday, 28 April 2012 at 20:59:48 UTC, q66 wrote:Who says D doesn't have duck-typing? template isADuck(T) { alias isADuck = is(typeof(T.quack())==bool); } void petADuck(T)(T duck) if (isADuck!T) { duck.quack(); } You can pass anything that has a quack() method to the function: struct CanadianDuck { void quack() { writeln("Quack, eh?"); } } class AmericanDuck { void quack() { writeln("Quack, yo!"); } } struct RubberDuck { void opDispatch!(string S)() { auto d = loadRuntimeDuckClass(); d.callMethod(S); } } struct Cow { void moo() { writeln("Mooo!"); } } void main() { CanadianDuck caddie; AmericanDuck quacker = new AmericanDuck; RubberDuck runtimeDuck; Cow orker; // Look, ma! I hez duck-taiping! petADuck(caddie); petADuck(quacker); petADuck(runtimeDuck); // Reject non-duck objects petADuck(orker); // compile error: orker is not a duck! } Not only D supports duck-typing, the compiler even checks type-safety for you at compile-time. ;-) Incidentally, this is what the Phobos range interface does. T -- My program has no bugs! Only undocumented features...This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.Python has two big drawbacks for large projects: - it's too slow - it's a dynamically-typed language The fact that it's flexible is because it uses duck typing, and AFAIK you can't do duck typing in a statically typed language. So it's cool for small programs, but it can't handle large ones because it's not statically typed. And this opinion doesn't come just out of thin air, I speak from my own professional experience.
Apr 28 2012
"H. S. Teoh" <hsteoh quickfur.ath.cx> wrote in message news:mailman.67.1335651468.24740.digitalmars-d puremagic.com...On Sat, Apr 28, 2012 at 11:12:38PM +0200, SomeDude wrote:Yea, templated code is structurally-typed (duck-typed) by default. Not a big fan of that personally, but I can live with it, and D is awesome enough that you can build nominal-typing out of it: http://www.semitwist.com/articles/EfficientAndFlexible/MultiplePages/Page5/On Saturday, 28 April 2012 at 20:59:48 UTC, q66 wrote:Who says D doesn't have duck-typing?This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.Python has two big drawbacks for large projects: - it's too slow - it's a dynamically-typed language The fact that it's flexible is because it uses duck typing, and AFAIK you can't do duck typing in a statically typed language. So it's cool for small programs, but it can't handle large ones because it's not statically typed. And this opinion doesn't come just out of thin air, I speak from my own professional experience.
Apr 28 2012
On Saturday, 28 April 2012 at 21:12:39 UTC, SomeDude wrote:On Saturday, 28 April 2012 at 20:59:48 UTC, q66 wrote:Go is a static duck typed language (when using interfaces anyway) AFAIK. http://golang.org/doc/go_faq.html#implements_interface http://research.swtch.com/interfaces /JonasThis kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.Python has two big drawbacks for large projects: - it's too slow - it's a dynamically-typed language The fact that it's flexible is because it uses duck typing, and AFAIK you can't do duck typing in a statically typed language. So it's cool for small programs, but it can't handle large ones because it's not statically typed. And this opinion doesn't come just out of thin air, I speak from my own professional experience.
Apr 29 2012
On Saturday, 28 April 2012 at 21:12:39 UTC, SomeDude wrote:[…] And this opinion doesn't come just out of thin air, I speak from my own professional experience.Regardless of the fact that I tend to agree with you on this one, isn't »my own professional experience« usually a synonym for »thin air«? ;) David
Apr 29 2012
On Sunday, 29 April 2012 at 09:52:21 UTC, David Nadlinger wrote:On Saturday, 28 April 2012 at 21:12:39 UTC, SomeDude wrote:Well yes and no. It's the difference between "I think that", and "I've experienced in real projects that". And well, discussing in another forum, I've had other similar echos and experiences. Basically, with Python and other dynamically typed languages, the time you gain writing code, you lose testing it and correcting bugs that a compiler would have found for you.[…] And this opinion doesn't come just out of thin air, I speak from my own professional experience.Regardless of the fact that I tend to agree with you on this one, isn't »my own professional experience« usually a synonym for »thin air«? ;) David
Apr 29 2012
On Saturday, 28 April 2012 at 20:59:48 UTC, q66 wrote:On Saturday, 28 April 2012 at 20:35:40 UTC, SomeDude wrote: This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.BTW, look at Scala for another language that's designed for large scale programming (as its name implies). Scala is a very good design, some even think it's the Java killer. But I think it's even more complex than D.
Apr 28 2012
Am 28.04.2012 22:59, schrieb q66:On Saturday, 28 April 2012 at 20:35:40 UTC, SomeDude wrote:Python is my favorite scripting language, but I would never propose a dynamic language for programming on the large. My employer does consulting for big projects. The type of entreprise projects that require multi-site development scattered across the globe, sometimes with 300+ developers. There is no way a dynamic language would work in such scenarios, without having a constant broken build on the CI system. -- PauloOn Saturday, 28 April 2012 at 20:09:50 UTC, q66 wrote:This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.On Saturday, 28 April 2012 at 20:05:30 UTC, SomeDude wrote: There are minimalistic languages that don't add too much complexity, instead it results in code being kept simple.I appreciate minimalistic languages. I love the simplicity of Scheme and the design of Lua. Lua and Python are extensible language, but truth be told, they cannot handle large scale programming. In fact, I don't know of any minimalistic language that can scale from hundreds of thousands to millions of lines of code. When you reach these sizes, their simple design becomes a drawback. You start missing lots of features. When you reach large scale programming, you want really powerful tools. That's basically what the Java designers discovered after experience. The original language was simple and easy, but that simplicity translated into way too much boilerplate code. So they kept adding features from version to version, generics, then annotations, a means to create new keywords. And now they would like to add delegates. These are all needed in large programs.D needs to do something it does really well and concentrate on that. Otherwise the language will remain being rather vague and doing "a bit of everything, but nothing truly well".It does a lot of things well already. Our point of comparison should languages that are designed to develop large systems. But most of all it needs to stabilize and polish, not change all the time. I think its feature set is very good already. We are far from having explored all its possibilities.Instead of adding more and more features into a rigid language, it needs to be made more flexible and extensible, both syntactically and semantically.
Apr 28 2012
On Sun, Apr 29, 2012 at 08:40:16AM +0200, Paulo Pinto wrote: [...]My employer does consulting for big projects. The type of entreprise projects that require multi-site development scattered across the globe, sometimes with 300+ developers. There is no way a dynamic language would work in such scenarios, without having a constant broken build on the CI system.[...] Yeah, at my work we have about 20-30 people working on a very large C/C++ codebase (one among many), and we already get broken builds every now and then, like bugs that completely break just about every feature in the system -- makes you wonder how any sane programmer could've checked in such a mess (and how said mess made it through the kangaroo code review process). Or blatant internal API breakages that make you wonder if anybody even *read* what they wrote. I cannot begin to imagine the horror of using a dynamic language in this setting. Static languages are already painful enough; throw in indeterminate typing at compile-time and it's a recipe for utter disaster, probably every single work day. And this is only 20-30 developers. The problem gets exponentially worse when that number goes up. At 300+ developers, the project would grind to a complete halt in less than a day (probably less than an hour). T -- Study gravitation, it's a field with a lot of potential.
Apr 29 2012
Am 29.04.2012 17:27, schrieb H. S. Teoh:On Sun, Apr 29, 2012 at 08:40:16AM +0200, Paulo Pinto wrote: [...]At 300+ developers, the project would grind to a complete halt inless than a day (probably less than an hour).Suffice to say, that on that specific project we had weeks without any working build, that had to be saved with hard code free rules until it got green again. This type of projects is what made me change my mind about static vs dynamic. Static languages with automatic type inference, and some type of dynamic dispatch like D's variant type/opDispatch, fullfil most use cases a dynamic language is good for, without sacrificing tooling or large scale development. -- Paulo
Apr 29 2012
On 29-04-2012 08:40, Paulo Pinto wrote:Am 28.04.2012 22:59, schrieb q66:Wait, dynamic-language programmers use CI? *ducks and runs* -- - AlexOn Saturday, 28 April 2012 at 20:35:40 UTC, SomeDude wrote:Python is my favorite scripting language, but I would never propose a dynamic language for programming on the large. My employer does consulting for big projects. The type of entreprise projects that require multi-site development scattered across the globe, sometimes with 300+ developers. There is no way a dynamic language would work in such scenarios, without having a constant broken build on the CI system. -- PauloOn Saturday, 28 April 2012 at 20:09:50 UTC, q66 wrote:This kind of attitude "we need big fat bullshit like Java and heavy use of OO and idioms and EH and all that other crap" is broken and false. And you have no way to prove that Python for example wouldn't scale for large projects; its main fault is that the default implementation is rather slow, but it's not pretty much missing anything required for a large project.On Saturday, 28 April 2012 at 20:05:30 UTC, SomeDude wrote: There are minimalistic languages that don't add too much complexity, instead it results in code being kept simple.I appreciate minimalistic languages. I love the simplicity of Scheme and the design of Lua. Lua and Python are extensible language, but truth be told, they cannot handle large scale programming. In fact, I don't know of any minimalistic language that can scale from hundreds of thousands to millions of lines of code. When you reach these sizes, their simple design becomes a drawback. You start missing lots of features. When you reach large scale programming, you want really powerful tools. That's basically what the Java designers discovered after experience. The original language was simple and easy, but that simplicity translated into way too much boilerplate code. So they kept adding features from version to version, generics, then annotations, a means to create new keywords. And now they would like to add delegates. These are all needed in large programs.D needs to do something it does really well and concentrate on that. Otherwise the language will remain being rather vague and doing "a bit of everything, but nothing truly well".It does a lot of things well already. Our point of comparison should languages that are designed to develop large systems. But most of all it needs to stabilize and polish, not change all the time. I think its feature set is very good already. We are far from having explored all its possibilities.Instead of adding more and more features into a rigid language, it needs to be made more flexible and extensible, both syntactically and semantically.
Apr 29 2012
On 28.04.2012 22:47, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?1. Drop is(...) feature entirely. Extend __traits where needed and move compile-time reflection to "magic" meta namespace completely. 2. "enum as manifest constant". Use static or immutable/global. Compiler should be smart enough to avoid putting immutable integers/doubles into object file as variables. 3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific. 4. foreach_reverse. Seriously let's kill this abomination. If it happens that foreach(x; retro(range)){...} is slower it just means compiler (inlining?) is no good and should be improved. 5. .tupleof looks like a hack. But I'd rather "refactor" than drop it. 6. Drop out arguments? There are tuples. And auto (a, b) = getMeTwoThings(); is cleanerthan <something> a, b; fillTheseTwoThings(a, b); // no indication whatsoever that a & b are modified heck even fn(&a, &b) in C is *better* (ok no tuple unpacking for now but you got the idea) 7. I can live without homogenous varaidics. Since most of the time they readily progress to full-blown variadics that detect common type & forward things to an array version of function. Also given that sometimes people do things like: this(int[] arr...)// ctor with cool syntax, yada-yada ;) { this.data = arr; //boom! (pointer to stack-allocated stuff) } 8. Something else. D is huge :) -- Dmitry Olshansky
Apr 28 2012
On 04/28/2012 09:22 PM, Dmitry Olshansky wrote:On 28.04.2012 22:47, Walter Bright wrote:static is not accessible at compile time, would you want to change that? immutable is not an option because it infects the type. Furthermore, I like 'enum' because it is concise. What is the issue with enum?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?1. Drop is(...) feature entirely. Extend __traits where needed and move compile-time reflection to "magic" meta namespace completely. 2. "enum as manifest constant". Use static or immutable/global.Compiler should be smart enoughSmart compiler fallacy. It really cannot be that smart in this case.to avoid putting immutable integers/doubles into object file as variables.Their address might be taken by code that is unavailable! Furthermore, many of my enums are strings or arrays.8. Something else. D is huge :)I actually think D is not too large.
Apr 28 2012
On 29.04.2012 0:57, Timon Gehr wrote:On 04/28/2012 09:22 PM, Dmitry Olshansky wrote:Oops, scratch that comment about static/immutable. But how about: alias thing = runSomeCtfe(); And bring the usual alias to new_name = <something>; form (even C++ finally got this right with C++11 aliases).On 28.04.2012 22:47, Walter Bright wrote:static is not accessible at compile time, would you want to change that? immutable is not an option because it infects the type.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?1. Drop is(...) feature entirely. Extend __traits where needed and move compile-time reflection to "magic" meta namespace completely. 2. "enum as manifest constant". Use static or immutable/global.Furthermore, I like 'enum' because it is concise. What is the issue with enum?For what it does - surely not. But in general it's big. For one it's not smaller then C++. 8. synchronized. scope(exit) mutex.unlock(); is fine in cases where RAII is awkward. -- Dmitry OlshanskyCompiler should be smart enoughSmart compiler fallacy. It really cannot be that smart in this case.to avoid putting immutable integers/doubles into object file as variables.Their address might be taken by code that is unavailable! Furthermore, many of my enums are strings or arrays.8. Something else. D is huge :)I actually think D is not too large.
Apr 28 2012
On 04/28/2012 11:04 PM, Dmitry Olshansky wrote:On 29.04.2012 0:57, Timon Gehr wrote:That would work in certain cases, where the initializer is not a single symbol. But then, I kinda like the way 'enum' is generalized in D: enum Foo{ member1, member2, member3, } => (allow non-integral enumerations) enum Foo{ member1 = "1", member2 = "2", member3 = "3", } => (anonymous enums) enum{ member1 = "1", member2 = "2", member3 = "3", } => (a single member is okay) enum{ member1 = "1", } => (syntactic sugar) enum member1 = "1";On 04/28/2012 09:22 PM, Dmitry Olshansky wrote:Oops, scratch that comment about static/immutable. But how about: alias thing = runSomeCtfe();On 28.04.2012 22:47, Walter Bright wrote:static is not accessible at compile time, would you want to change that? immutable is not an option because it infects the type.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?1. Drop is(...) feature entirely. Extend __traits where needed and move compile-time reflection to "magic" meta namespace completely. 2. "enum as manifest constant". Use static or immutable/global.And bring the usual alias to new_name = <something>; form (even C++ finally got this right with C++11 aliases).This is probably something that should be done.I am not sure how to compare, but D 'feels' smaller than C++ to me. Implementing a compiler is probably harder for D, because of the interplay of forward references, CTFE and compile time introspection.I actually think D is not too large.For what it does - surely not. But in general it's big. For one it's not smaller then C++.
Apr 28 2012
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jnhpvv$ih4$1 digitalmars.com...On 04/28/2012 11:04 PM, Dmitry Olshansky wrote:Those are good. They are essentially enumerations.But how about: alias thing = runSomeCtfe();That would work in certain cases, where the initializer is not a single symbol. But then, I kinda like the way 'enum' is generalized in D: enum Foo{ member1, member2, member3, } => (allow non-integral enumerations) enum Foo{ member1 = "1", member2 = "2", member3 = "3", }=> (anonymous enums) enum{ member1 = "1", member2 = "2", member3 = "3", }I don't think "anonymous enum" makes any sense at all. It's *not* an enumeration by any stretch of the term, it's just a series of manifest constants. The fact that they're grouped doesn't even have any semantic consequence, as far as I'm aware.=> (a single member is okay) enum{ member1 = "1", } => (syntactic sugar) enum member1 = "1";Just simpler examples of the above, which isn't any form of enumeration at all.Emphatic +1 I always have to stop and think carefully about the order when I write an alias.And bring the usual alias to new_name = <something>; form (even C++ finally got this right with C++11 aliases).This is probably something that should be done.Implementing a compiler is probably harder for D, because of the interplay of forward references, CTFE and compile time introspection.Those make D more difficult to implement than many languages, but OTOH, AIUI, C++ has some real nightmarish details with templates and even just simply parsing. Probably some other bizarre cruft, too. IIRC, I think Walter's occasionally mentioned something about the...overload rules?
Apr 28 2012
On 04/29/2012 08:35 AM, Nick Sabalausky wrote:"Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jnhpvv$ih4$1 digitalmars.com...enum{ member1, member2, member3, } static assert(member1+1==member2 && member2+1==member3);On 04/28/2012 11:04 PM, Dmitry Olshansky wrote:Those are good. They are essentially enumerations.But how about: alias thing = runSomeCtfe();That would work in certain cases, where the initializer is not a single symbol. But then, I kinda like the way 'enum' is generalized in D: enum Foo{ member1, member2, member3, } => (allow non-integral enumerations) enum Foo{ member1 = "1", member2 = "2", member3 = "3", }=> (anonymous enums) enum{ member1 = "1", member2 = "2", member3 = "3", }I don't think "anonymous enum" makes any sense at all. It's *not* an enumeration by any stretch of the term,it's just a series of manifest constants. The fact that they're grouped doesn't even have any semantic consequence, as far as I'm aware.The only differences are that they don't occupy their own namespace and they don't define their own type. But non-anonymous enums are _just a bunch of manifest constants_ as well! Therefore there are ways in which the generalisation makes sense.'enum' declares manifest constants whether or not it is anonymous. Afaik go uses 'const' for enumerations and manifest constants. 'const' means a different thing in D. (arguably, 'readonly' would be a better fit) I don't think that the exact keywords matter a huge deal here.=> (a single member is okay) enum{ member1 = "1", } => (syntactic sugar) enum member1 = "1";Just simpler examples of the above, which isn't any form of enumeration at all.
Apr 29 2012
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jnj92m$306m$1 digitalmars.com...On 04/29/2012 08:35 AM, Nick Sabalausky wrote:No, they're not. Non-anon enums *contain* a bunch of manifest constants. But what non-anon enums *are* is a type. Anon enums are not a type at all. I think that's a significant difference. Note this is in stark contrast to: - Classes: Anonymous or not, it's still a type. - Functions: Anonymous or not, it's still *not* a type. The syntaxes we have for anon enums and non-anon enums makes them *look* like they're basically the same thing, just with/without a name, but that's not actually the case. Of course, my biggest issue by far is with the name "enum". Non-anon enums can reasonably be thought of as enumerations (except for bitfields, but I think those should be handled differently from enums anyway). But anon-enums are just plain not enumerations, period. If we weren't calling them all "enum", then I would have much, much less problem with the syntax we have. And yea, I get the whole "What's in a name?", but "enum" is just a colossally *terrible* name for this. It's worse than when "immutable" was called "invariant".it's just a series of manifest constants. The fact that they're grouped doesn't even have any semantic consequence, as far as I'm aware.The only differences are that they don't occupy their own namespace and they don't define their own type. But non-anonymous enums are _just a bunch of manifest constants_ as well!
Apr 29 2012
On 04/29/2012 12:12 PM, Nick Sabalausky wrote:"Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jnj92m$306m$1 digitalmars.com...constants. ButOn 04/29/2012 08:35 AM, Nick Sabalausky wrote:No, they're not. Non-anon enums *contain* a bunch of manifestit's just a series of manifest constants. The fact that they're grouped doesn't even have any semantic consequence, as far as I'm aware.The only differences are that they don't occupy their own namespace and they don't define their own type. But non-anonymous enums are _just a bunch of manifest constants_ as well!what non-anon enums *are* is a type. Anon enums are not a type at all. I think that's a significant difference.I see that way as well. I have a section titled "enum values that are not of an enum type" at http://ddili.org/ders/d.en/enum.html: [quote] sometimes it may not be natural to come up with enum type names just to use named constants. Let's assume that a named constant is needed to represent the number of seconds per day. It should not be necessary to also define an enum type for this constant value. All that is needed is a constant value that can be referred to by its name. In such cases, the type of the enum and the value parentheses are not specified: enum secondsPerDay = 60 * 60 * 24; [/quote]Of course, my biggest issue by far is with the name "enum".Agreed. It became a bad name as soon as any value other than a number could be an enum value (or "member").Non-anon enums can reasonably be thought of as enumerations (except for bitfields, but I think those should be handled differently from enums anyway). Butanon-enumsare just plain not enumerations, period. If we weren't calling them all "enum", then I would have much, much less problem with the syntax wehave.And yea, I get the whole "What's in a name?", but "enum" is just a colossally *terrible* name for this. It's worse than when "immutable" was called "invariant".Ali
Apr 30 2012
On Sun, Apr 29, 2012 at 02:35:07AM -0400, Nick Sabalausky wrote:"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jnhpvv$ih4$1 digitalmars.com...[...][...] It has been said that C++ cannot be lexed before it's parsed. Before C++11, for example, this is invalid: std::vector<std::vector<T>> nestedList; Instead, you have to write: std::vector<std::vector<T> > nestedList; Fortunately they fixed this in C++11. But now you have another problem: std::vector<myTemplate<T>>1> nestedList; Whether or not this is valid depends on whether T is a type name or a variable name (e.g., if myTemplate takes an int parameter). But how is the lexer even supposed to know whether the >> should be a right shift operator or two right angle brackets? It has to understand the _semantics_ of T before it can even lex the thing. I read somewhere that one of D's goals was to be able to lex the language without requiring semantic knowledge in the lexer. You have no idea how much such a seemingly-obvious concept can save hours, days, nay, months and years of frustration in compiler implementation. So you think D is hard to implement? We have barely even begun to delve into the insane convolutions of C++. You'll start to have some real hair-tearing sessions once you start getting into implicit conversion rules and template best-match algorithms. Be glad, be very glad that we have D instead of C++! T -- Designer clothes: how to cover less by paying more.Implementing a compiler is probably harder for D, because of the interplay of forward references, CTFE and compile time introspection.Those make D more difficult to implement than many languages, but OTOH, AIUI, C++ has some real nightmarish details with templates and even just simply parsing. Probably some other bizarre cruft, too. IIRC, I think Walter's occasionally mentioned something about the...overload rules?
Apr 29 2012
On Sunday, 29 April 2012 at 15:16:57 UTC, H. S. Teoh wrote:[…] and template best-match algorithms. Be glad, be very glad that we have D instead of C++!To be fair, the template matching logic in D is quite complicated as well (at least I can recall several instances of stumbling over bugs in the implementation, would have to search Bugzilla for details) – the only thing is that we don't really have a formal spec for it yet… David
Apr 29 2012
On 04/29/2012 05:17 PM, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 02:35:07AM -0400, Nick Sabalausky wrote:C++ implementation complexity is incidental."Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jnhpvv$ih4$1 digitalmars.com...[...][...]Implementing a compiler is probably harder for D, because of the interplay of forward references, CTFE and compile time introspection.Those make D more difficult to implement than many languages, but OTOH, AIUI, C++ has some real nightmarish details with templates and even just simply parsing. Probably some other bizarre cruft, too. IIRC, I think Walter's occasionally mentioned something about the...overload rules?It has been said that C++ cannot be lexed before it's parsed. Before C++11, for example, this is invalid: std::vector<std::vector<T>> nestedList; Instead, you have to write: std::vector<std::vector<T> > nestedList; Fortunately they fixed this in C++11. But now you have another problem: std::vector<myTemplate<T>>1> nestedList; Whether or not this is valid depends on whether T is a type name or a variable nameI think it is never valid.(e.g., if myTemplate takes an int parameter). But how is the lexer even supposed to know whether the>> should be a right shift operator or two right angle brackets? It has to understand the _semantics_ of T before it can even lex the thing.A D compiler has to semantically analyse the code without full information about which symbols are declared, (getting the full set of declared symbols is actually an ill-defined problem because conditional compilation is Turing complete and can already depend on any declared symbol or even on the fact that a certain symbol has _not_ been declared). There might also be ambiguities or contradictions in the code that a compiler should detect. There is no mention of this issue or its (necessarily conservative and somewhat arbitrary) solution in the language documentation. DMD does not solve the problem, but just fails in funny ways when faced with a non-trivial instance of it. C++ does not have such issues at all because it disallows forward references! Don't get me wrong, I think this is rather awesome. But I predict it will be somewhat of a roadblock for getting the language into a stable state.I read somewhere that one of D's goals was to be able to lex the language without requiring semantic knowledge in the lexer.This is required in order to have forward references.You have no ideaI do.how much such a seemingly-obvious concept can save hours, days, nay, months and years of frustration in compiler implementation. So you think D is hard to implement? We have barely even begun to delve into the insane convolutions of C++. You'll start to have some real hair-tearing sessions once you start getting into implicit conversion rulesWell, again, DMD does not get those right. And there is some black magic in that area, because the implicitly-converts-to-relation is from expressions to types instead of from types to types. (which is awesome of course, but it is complex to get right). Try this (this *should* compile). pragma(msg, typeof(1?[[]]:[[1]])); pragma(msg, typeof(1?1?[[]]:[[]]:[[1]])); pragma(msg, typeof([[[]],[[]],[[1]]])); class C{} static C[] c = [null]; pragma(msg, typeof([[null],[new C]]));and template best-match algorithms. Be glad, be very glad that we have D instead of C++!static if(!is(typeof(foo))) enum bar = 1; static if(!is(typeof(bar))) enum foo = 1; In D, most of the complexity stems from its advanced features, while in C++ a lot of the complexity is merely incidental.
Apr 29 2012
2. "enum as manifest constant". Use static or immutable/global. Compiler should be smart enough to avoid putting immutable integers/doubles into object file as variables.But enums aren't only used for optimization. What if you want to use a constant at compile time, as a template parameter?
Apr 28 2012
On 28/04/2012 20:22, Dmitry Olshansky wrote:3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific.My primary use case for the with() statement is with final switch: final switch(something) with(MyEnumWithAPrettyLongName) { case A: // Save repeating myself everywhere break; . . . } -- Robert http://octarineparrot.com/
Apr 29 2012
On 30-04-2012 02:40, Robert Clipsham wrote:On 28/04/2012 20:22, Dmitry Olshansky wrote:Hah, clever! Never would've thought of that. -- - Alex3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific.My primary use case for the with() statement is with final switch: final switch(something) with(MyEnumWithAPrettyLongName) { case A: // Save repeating myself everywhere break; . . . }
Apr 29 2012
On 2012-04-30 02:40, Robert Clipsham wrote:On 28/04/2012 20:22, Dmitry Olshansky wrote:That's the only thing I used the with-statement for. -- /Jacob Carlborg3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific.My primary use case for the with() statement is with final switch: final switch(something) with(MyEnumWithAPrettyLongName) { case A: // Save repeating myself everywhere break; . . . }
Apr 30 2012
On Mon, 30 Apr 2012 09:39:15 +0200, Jacob Carlborg <doob me.com> wrote:On 2012-04-30 02:40, Robert Clipsham wrote:http://msdn.microsoft.com/en-us/library/bb384062.aspxOn 28/04/2012 20:22, Dmitry Olshansky wrote:That's the only thing I used the with-statement for.3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific.My primary use case for the with() statement is with final switch: final switch(something) with(MyEnumWithAPrettyLongName) { case A: // Save repeating myself everywhere break; . . . }
Apr 30 2012
On Monday, 30 April 2012 at 07:49:48 UTC, simendsjo wrote:http://msdn.microsoft.com/en-us/library/bb384062.aspxOoh, nice - care to share?
Apr 30 2012
On Mon, 30 Apr 2012 11:31:49 +0200, John Chapman <johnch_atms hotmail.com> wrote:On Monday, 30 April 2012 at 07:49:48 UTC, simendsjo wrote:Basically just auto c = new C; with(c) { field = value; }http://msdn.microsoft.com/en-us/library/bb384062.aspxOoh, nice - care to share?
Apr 30 2012
On 30 April 2012 10:39, Jacob Carlborg <doob me.com> wrote:On 2012-04-30 02:40, Robert Clipsham wrote:That's the only thing I was aware it did ;) .. are there other uses?On 28/04/2012 20:22, Dmitry Olshansky wrote:That's the only thing I used the with-statement for.3. with statement (?). I kind of like it but bleh it's too boggy and it doesn't seem to pull its weight. (pointers? class references? a lot of stuff to go wrong) Fluent interfaces solve a good portion of its benefits to be specific.My primary use case for the with() statement is with final switch: final switch(something) with(**MyEnumWithAPrettyLongName) { case A: // Save repeating myself everywhere break; . . . }
Apr 30 2012
On 2012-04-30 12:29, Manu wrote:On 30 April 2012 10:39, Jacob Carlborg <doob me.com That's the only thing I used the with-statement for. That's the only thing I was aware it did ;) .. are there other uses?You can use it to access members without a receiver as well: class Foo { int x; int y; } auto foo = new Foo; with (foo) { x = 3; y = 4; } http://dlang.org/statement.html#WithStatement -- /Jacob Carlborg
Apr 30 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementations - Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable value - Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad) I think I would find some more, but these are the ones I can recall now.
Apr 28 2012
"q66" <quaker66 gmail.com> wrote in message news:ihqjguujvoukhlqcwkyi forum.dlang.org...- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable valueThat's just craziness!
Apr 28 2012
On 04/28/2012 09:39 PM, Nick Sabalausky wrote:"q66"<quaker66 gmail.com> wrote in message news:ihqjguujvoukhlqcwkyi forum.dlang.org...+1.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable valueThat's just craziness!
Apr 28 2012
Am Sat, 28 Apr 2012 15:39:49 -0400 schrieb "Nick Sabalausky" <SeeWebsiteToContactMe semitwist.com>:"q66" <quaker66 gmail.com> wrote in message news:ihqjguujvoukhlqcwkyi forum.dlang.org...Madness even! AAs are soon mostly in the library and that's a good trade-off; trusted system needs to be there as long as there is safe; exception handling - some people rely on it heavily. See it as the easy way to error out of a function that doesn't normally return anything and cascade up several calls, while being able to release resources in each. I don't know about Phobos. Some batteries included are nice and help the popularity. When it comes to bindings to third party products with many alternatives, like databases, I'd say one should cut it there definitly. I can agree on the rest. -- Marco- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable valueThat's just craziness!
Apr 28 2012
"Marco Leise" <Marco.Leise gmx.de> wrote in message news:20120429075404.121a5a46 marco-leise...I don't know about Phobos. Some batteries included are nice and help the popularity. When it comes to bindings to third party products with many alternatives, like databases, I'd say one should cut it there definitly.Yea, it's a tradeoff either way. Once we have a mature "D CPAN", there will be less reason to pack things into Phobos. But until that actually happens, a "batteries included"-style std lib is necessary. And of course, like you say, there are likely things that just aren't appropriate for the std lib either way.
Apr 28 2012
On Sunday, 29 April 2012 at 05:54:10 UTC, Marco Leise wrote:Am Sat, 28 Apr 2012 15:39:49 -0400 schrieb "Nick Sabalausky" <SeeWebsiteToContactMe semitwist.com>:I don't want AA to be removed from the core language. That would be a big step backward in my opinion. Core language AAs are entirely adequate for a lot of applications, and they make for so much cleaner and easier to read/write code than template notation."q66" <quaker66 gmail.com> wrote in message news:ihqjguujvoukhlqcwkyi forum.dlang.org...Madness even! AAs are soon mostly in the library and that's a good trade-off; trusted system needs to be there as long as there is safe; exception handling - some people rely on it heavily. See it as the easy way to error out of a function that doesn't normally return anything and cascade up several calls, while being able to release resources in each. I don't know about Phobos. Some batteries included are nice and help the popularity. When it comes to bindings to third party products with many alternatives, like databases, I'd say one should cut it there definitly. I can agree on the rest.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable valueThat's just craziness!
Apr 29 2012
"SomeDude" <lovelydear mailmetrash.com> wrote in message news:jrdmqmchgbibqmrwzwsk forum.dlang.org...On Sunday, 29 April 2012 at 05:54:10 UTC, Marco Leise wrote:There will still be sugar in the compiler so they appear to be builtins. When the switch happens, I'm sure it'll be transparent - average users probably won't even notice. It's just that "behind the scenes" their implementation will move from DMD to Druntime.Am Sat, 28 Apr 2012 15:39:49 -0400 Madness even! AAs are soon mostly in the library and that's a good trade-off; trusted system needs to be there as long as there is safe; exception handling - some people rely on it heavily. See it as the easy way to error out of a function that doesn't normally return anything and cascade up several calls, while being able to release resources in each. I don't know about Phobos. Some batteries included are nice and help the popularity. When it comes to bindings to third party products with many alternatives, like databases, I'd say one should cut it there definitly. I can agree on the rest.I don't want AA to be removed from the core language. That would be a big step backward in my opinion. Core language AAs are entirely adequate for a lot of applications, and they make for so much cleaner and easier to read/write code than template notation.
Apr 29 2012
"Nick Sabalausky" <SeeWebsiteToContactMe semitwist.com> wrote in message news:jnit81$29uh$1 digitalmars.com..."SomeDude" <lovelydear mailmetrash.com> wrote in message news:jrdmqmchgbibqmrwzwsk forum.dlang.org...In fact, don't regular arrays already work like this?On Sunday, 29 April 2012 at 05:54:10 UTC, Marco Leise wrote:There will still be sugar in the compiler so they appear to be builtins. When the switch happens, I'm sure it'll be transparent - average users probably won't even notice. It's just that "behind the scenes" their implementation will move from DMD to Druntime.Am Sat, 28 Apr 2012 15:39:49 -0400 Madness even! AAs are soon mostly in the library and that's a good trade-off; trusted system needs to be there as long as there is safe; exception handling - some people rely on it heavily. See it as the easy way to error out of a function that doesn't normally return anything and cascade up several calls, while being able to release resources in each. I don't know about Phobos. Some batteries included are nice and help the popularity. When it comes to bindings to third party products with many alternatives, like databases, I'd say one should cut it there definitly. I can agree on the rest.I don't want AA to be removed from the core language. That would be a big step backward in my opinion. Core language AAs are entirely adequate for a lot of applications, and they make for so much cleaner and easier to read/write code than template notation.
Apr 29 2012
On Sunday, 29 April 2012 at 08:13:53 UTC, Nick Sabalausky wrote:There will still be sugar in the compiler so they appear to be builtins. When the switch happens, I'm sure it'll be transparent - average users probably won't even notice. It's just that "behind the scenes" their implementation will move from DMD to Druntime.Hmmm, sounds nice, but bolting the language with the standard library is very risky (and a rather bad idea imho). Unless there is a very lightweight minimalistic core for Phobos (something which I advocate), you bolt a heavyweight library to your language, and that's not good. I'd rather keep the integrated the AAs, which are fine for most applications, and have templated AAs in the library for heavier use. Even though it may seem redundant, it's just as redundant as having arrays in the core language and std.array. Noone would want to remove arrays from the core language, right ?
Apr 29 2012
On 04/29/2012 10:28 AM, SomeDude wrote:On Sunday, 29 April 2012 at 08:13:53 UTC, Nick Sabalausky wrote:druntime is the library it will be moved into, not Phobos.There will still be sugar in the compiler so they appear to be builtins. When the switch happens, I'm sure it'll be transparent - average users probably won't even notice. It's just that "behind the scenes" their implementation will move from DMD to Druntime.Hmmm, sounds nice, but bolting the language with the standard library is very risky (and a rather bad idea imho). Unless there is a very lightweight minimalistic core for Phobos (something which I advocate), you bolt a heavyweight library to your language, and that's not good.
Apr 29 2012
On Sunday, 29 April 2012 at 08:31:57 UTC, Timon Gehr wrote:druntime is the library it will be moved into, not Phobos.Ah, that's ok, then.
Apr 29 2012
On Sun, Apr 29, 2012 at 10:28:47AM +0200, SomeDude wrote:On Sunday, 29 April 2012 at 08:13:53 UTC, Nick Sabalausky wrote:[...] Please note that the AA implementation will be moving into druntime, NOT phobos. The compiler already depends on a bunch of stuff in druntime (the GC being a prime example, and the Object class being another). And every time you write 'typeid'? That's druntime code too. T -- It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels.There will still be sugar in the compiler so they appear to be builtins. When the switch happens, I'm sure it'll be transparent - average users probably won't even notice. It's just that "behind the scenes" their implementation will move from DMD to Druntime.Hmmm, sounds nice, but bolting the language with the standard library is very risky (and a rather bad idea imho). Unless there is a very lightweight minimalistic core for Phobos (something which I advocate), you bolt a heavyweight library to your language, and that's not good.
Apr 29 2012
On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementations - Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable value - Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad) I think I would find some more, but these are the ones I can recall now.I disagree with every single point here.
Apr 28 2012
On Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementations - Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable value - Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad) I think I would find some more, but these are the ones I can recall now.I disagree with every single point here.
Apr 28 2012
On Saturday, 28 April 2012 at 20:02:12 UTC, q66 wrote:On Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:Sorry, with that, I agree. Nick Sabalausky proposed to remove version entirely. But I agree there could be something like: version(LINUX|OSX){ ... } else { ... }On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?
Apr 28 2012
On Sat, Apr 28, 2012 at 10:08:29PM +0200, SomeDude wrote:On Saturday, 28 April 2012 at 20:02:12 UTC, q66 wrote:But if you're gonna do that, might as well just fold the feature into static if. The point of having a separate version construct was to provide a very basic, simple, easy-to-implement and easy-to-use way of versioning stuff. I don't think it was ever intended to be a full-fledged versioning system. T -- What doesn't kill me makes me stranger.On Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:Sorry, with that, I agree. Nick Sabalausky proposed to remove version entirely. But I agree there could be something like: version(LINUX|OSX){ ... } else { ... }On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?
Apr 28 2012
On Saturday, 28 April 2012 at 20:51:54 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 10:08:29PM +0200, SomeDude wrote:I really don't care how it's implemented or what its syntax is. What I do want is begin able with a single glimpse, to see the different versions of the code, without having the impression to plunge into a "static if hell" with 5 levels of indentation. Having a different keyword helps for this. Besides, a specific keyword makes parsing code easier.On Saturday, 28 April 2012 at 20:02:12 UTC, q66 wrote:But if you're gonna do that, might as well just fold the feature into static if. The point of having a separate version construct was to provide a very basic, simple, easy-to-implement and easy-to-use way of versioning stuff. I don't think it was ever intended to be a full-fledged versioning system. TOn Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:Sorry, with that, I agree. Nick Sabalausky proposed to remove version entirely. But I agree there could be something like: version(LINUX|OSX){ ... } else { ... }On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?
Apr 28 2012
"SomeDude" <lovelydear mailmetrash.com> wrote in message news:sxzgfzztxfvsstwrqdiu forum.dlang.org...On Saturday, 28 April 2012 at 20:02:12 UTC, q66 wrote:FWIW, one of the big wins I see in migrating "version" to "static if" is switching from the clumbsy "defined/undefined" model to a model of "true/false, undefined is an error". The current "undefined is not an error" stuff is just so...ActionScript 2.On Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:Sorry, with that, I agree. Nick Sabalausky proposed to remove version entirely. But I agree there could be something like: version(LINUX|OSX){ ... } else { ... }On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?
Apr 28 2012
On Sunday, 29 April 2012 at 06:10:40 UTC, Nick Sabalausky wrote:"SomeDude" <lovelydear mailmetrash.com> wrote in message news:sxzgfzztxfvsstwrqdiu forum.dlang.org...I don't mind changing the semantics of "version", but replacing the KEYWORD "version" with "static if" will make for code that is harder to read for the eye, harder to parse for the tools, and overall uglier. So I want to keep the keyword, which is a very good addition in my opinion.On Saturday, 28 April 2012 at 20:02:12 UTC, q66 wrote:FWIW, one of the big wins I see in migrating "version" to "static if" is switching from the clumbsy "defined/undefined" model to a model of "true/false, undefined is an error". The current "undefined is not an error" stuff is just so...ActionScript 2.On Saturday, 28 April 2012 at 19:57:08 UTC, SomeDude wrote:Sorry, with that, I agree. Nick Sabalausky proposed to remove version entirely. But I agree there could be something like: version(LINUX|OSX){ ... } else { ... }On Saturday, 28 April 2012 at 19:23:00 UTC, q66 wrote:So you don't agree version() is horribly half assed without AND/OR (how do you generate the same code for two different versions without copying or creating a new version covering both cases then?) and that "version = FOO;" makes no sense?
Apr 29 2012
On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for PerlUm... that's what a *library* is supposed to be: a large collection of useful stuff from which you can pick the few that you need right now.- Properties - they're kinda broken at this point and the value is questionableWhat kind of properties are you referring to?- trusted systemThese are necessary.- Exception handling - a lot of runtime, questionable valueI completely disagree. No exception handling means lots and lots and lots of boilerplate code for checking error codes, return values, which are too tedious to write, which translates to many people leaving them out and ending up with unreliable code that fail silently or crash outright when a function call they assumed would work stopped working. If you've worked in large multi-person projects, you'll see very quickly why you *need* exception handling. No modern language can do without exception handling. Maybe you have a beef with how it's currently done in D, but regardless, you *need* exception handling of some kind.- Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad)[...] I find versions sorta neat... and they're simple enough that they don't add to much bloat to the language. (Whereas if you added AND and OR to them, then they start duplicating the function of static if, and that's when they become redundant.) T -- Your inconsistency is the only consistent thing about you! -- KD
Apr 28 2012
On Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]Besides AA literals, library can handle this JUST FINE.- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.Too large collection becomes too hard to manage. Separating it and distributing in style "you pay for what you use" is IMO the right approach.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for PerlUm... that's what a *library* is supposed to be: a large collection of useful stuff from which you can pick the few that you need right now.The property crap. It's broken. If anything, it needs something- Properties - they're kinda broken at this point and the value is questionableWhat kind of properties are you referring to?They're far from necessary.- trusted systemThese are necessary.The exception handling system via try/catch is as bad and tedious as error codes, except the added runtime. It all roots from the idea "catch everything that throws". This is broken, as you DON'T always need to handle all sorts of errors (letting it segfault or something sometimes simply proves to be better than trying to save the situation; or you can simply assert it). Also http://yosefk.com/c++fqa/exceptions.html#fqa-17.1- Exception handling - a lot of runtime, questionable valueI completely disagree. No exception handling means lots and lots and lots of boilerplate code for checking error codes, return values, which are too tedious to write, which translates to many people leaving them out and ending up with unreliable code that fail silently or crash outright when a function call they assumed would work stopped working. If you've worked in large multi-person projects, you'll see very quickly why you *need* exception handling. No modern language can do without exception handling. Maybe you have a beef with how it's currently done in D, but regardless, you *need* exception handling of some kind.They're nearly unusable now. And the syntax simply makes no sense.- Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad)[...] I find versions sorta neat... and they're simple enough that they don't add to much bloat to the language. (Whereas if you added AND and OR to them, then they start duplicating the function of static if, and that's when they become redundant.)T
Apr 28 2012
On Saturday, 28 April 2012 at 21:05:12 UTC, q66 wrote:On Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:Yeah, but core language AA are so useful it would be a MAJOR mistake to remove them. In Python too, you could put the AA in the libraries. Yet everybody uses the AA that are in the language. Where I DO agree with you is, Phobos should be a two level library, i.e a minimalistic library, with about the same feature set as the standard C library + multithreading, and a superset with the full range of features (ranges, algorithms, etc). I've already advocated it somewhere else.On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]Besides AA literals, library can handle this JUST FINE.- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.
Apr 28 2012
On 28-04-2012 23:18, SomeDude wrote:On Saturday, 28 April 2012 at 21:05:12 UTC, q66 wrote:Let's get a standard package manager that we either advocate on dlang.org or include in the releases before we start talking about reducing the amount of modules in Phobos. -- - AlexOn Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:Yeah, but core language AA are so useful it would be a MAJOR mistake to remove them. In Python too, you could put the AA in the libraries. Yet everybody uses the AA that are in the language. Where I DO agree with you is, Phobos should be a two level library, i.e a minimalistic library, with about the same feature set as the standard C library + multithreading, and a superset with the full range of features (ranges, algorithms, etc). I've already advocated it somewhere else.On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]Besides AA literals, library can handle this JUST FINE.- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.
Apr 29 2012
On Sunday, 29 April 2012 at 20:00:27 UTC, Alex Rønne Petersen wrote:Let's get a standard package manager that we either advocate on dlang.org or include in the releases before we start talking about reducing the amount of modules in Phobos.Don't get me wrong. I don't want to reduce the amount of modules in Phobos. I think it's a great standard library. A little bit buggy in some places, and lacks a few important features (that are in the review queue), but great overall. I fear the risk with a package system is, having some parts of Phobos not being correctly maintained with time. And I want to be able to have the whole thing with a single download. No, my concern was, for smaller applications, in embedded systems for instance (Android, iOS, etc), there is not really a small basic library. So I would think of a two level standard library, one on top of the other. OTOH, Jonathan Davis made the remark that we can always use the C lib and its bindings, so this mostly satisfies my concern.
Apr 29 2012
On 29 April 2012 23:00, Alex R=C3=B8nne Petersen <xtzgzorex gmail.com> wrot= e:On 28-04-2012 23:18, SomeDude wrote:or include in the releases before we start talking about reducing theYeah, but core language AA are so useful it would be a MAJOR mistake to remove them. In Python too, you could put the AA in the libraries. Yet everybody uses the AA that are in the language. Where I DO agree with you is, Phobos should be a two level library, i.e a minimalistic library, with about the same feature set as the standard C library + multithreading, and a superset with the full range of features (ranges, algorithms, etc). I've already advocated it somewhere else.Let's get a standard package manager that we either advocate on dlang.org=amount of modules in Phobos.Oh hell yes! I have exciting dreams of something like this every other night ;)
Apr 29 2012
On 2012-04-30 00:07, Manu wrote:On 29 April 2012 23:00, Alex Rønne Petersen <xtzgzorex gmail.com <mailto:xtzgzorex gmail.com>> wrote:Let's get a standard package manager that we either advocate on dlang.org <http://dlang.org> or include in the releases before we start talking about reducing the amount of modules in Phobos. Oh hell yes! I have exciting dreams of something like this every other night ;)I'm working on this. Unfortunately I cannot work on this full-time so basically nothing gets done. https://github.com/jacob-carlborg/orbit/wiki/Orbit-Package-Manager-for-D https://github.com/jacob-carlborg/orbit -- /Jacob Carlborg
Apr 30 2012
On Mon, 30 Apr 2012 09:24:44 +0200, Jacob Carlborg <doob me.com> wrote:On 2012-04-30 00:07, Manu wrote:On 29 April 2012 23:00, Alex R=C3=B8nne Petersen <xtzgzorex gmail.com=<mailto:xtzgzorex gmail.com>> wrote:Let's get a standard package manager that we either advocate on dlang.org <http://dlang.org> or include in the releases before we=rstart talking about reducing the amount of modules in Phobos. Oh hell yes! I have exciting dreams of something like this every othe==night ;)I'm working on this. Unfortunately I cannot work on this full-time so =basically nothing gets done. https://github.com/jacob-carlborg/orbit/wiki/Orbit-Package-Manager-for=-Dhttps://github.com/jacob-carlborg/orbitVibe.d has its own: = https://github.com/rejectedsoftware/vibe.d/tree/master/source/vibe/vpm And we have dsss: https://github.com/apriori/dsss And it seems this might be related too: = https://github.com/dbuilder-developers/dbuilder Getting orbit up and running would have been great.
Apr 30 2012
On 2012-04-30 09:32, simendsjo wrote:Vibe.d has its own: https://github.com/rejectedsoftware/vibe.d/tree/master/source/vibe/vpm And we have dsss: https://github.com/apriori/dsss"This project is currently on ice in favor of porting orbit from D1 to D2 and continue its implemention. Orbit will cover the same featureset as dsss and much more." BTW, Orbit is already ported to D2.And it seems this might be related too: https://github.com/dbuilder-developers/dbuilderThis seems to be a build tool and not a package manager.Getting orbit up and running would have been great.-- /Jacob Carlborg
Apr 30 2012
On 04/28/2012 11:05 PM, q66 wrote:On Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:That is why they should be a narrow wrapper around a library defined type.On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]Besides AA literals, library can handle this JUST FINE.- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.This sounds reasonable.Too large collection becomes too hard to manage. Separating it and distributing in style "you pay for what you use" is IMO the right approach.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for PerlUm... that's what a *library* is supposed to be: a large collection of useful stuff from which you can pick the few that you need right now.As I understand it, the 'agreed upon' design is that property int foo() { return x; } property void foo(int v) { x = v; } int foo { set{ x = value; }; get{ return x; } } I think it is even perfectly fine to just allow function calls without parentheses, but I wouldn't mind seeing that feature gone.The property crap. It's broken. If anything, it needs something like in- Properties - they're kinda broken at this point and the value is questionableWhat kind of properties are you referring to?Why? Memory safety is generally considered to be important.They're far from necessary.- trusted systemThese are necessary.It can improve performance though, because the exceptional branches don't occur in the code that is normally executed.The exception handling system via try/catch is as bad and tedious as error codes, except the added runtime.- Exception handling - a lot of runtime, questionable valueI completely disagree. No exception handling means lots and lots and lots of boilerplate code for checking error codes, return values, which are too tedious to write, which translates to many people leaving them out and ending up with unreliable code that fail silently or crash outright when a function call they assumed would work stopped working. If you've worked in large multi-person projects, you'll see very quickly why you *need* exception handling. No modern language can do without exception handling. Maybe you have a beef with how it's currently done in D, but regardless, you *need* exception handling of some kind.It all roots from the idea "catch everything that throws". This is broken, as you DON'T always need to handle all sorts of errors (letting it segfault or something sometimes simply proves to be better than trying to save the situation;Except that it won't necessarily segfault. That is not how _reliable_ systems work. Robustness is an important property of critical systems. If your software might kill people if it behaves in the wrong way, you really really don't want to ignore error conditions.or you can simply assert it).Certainly, if it is a consistency criterion internal to the program, then assertions should be used.Also http://yosefk.com/c++fqa/exceptions.html#fqa-17.1 [snip.]The part of this article relevant for D is this: "Still, in many cases, the benefits of exceptions are more important than their problems. For example, if your language manages memory automatically, the problem of releasing acquired resources becomes a small one (you only have to care about files, etc., which are a tiny part of the "resources" used by a program - most of the "resources" are memory). If your language throws exceptions when you violate its rules (for example, upon out-of-bounds array access), these exceptions will help you find lots of bugs, especially if you can get the call stack from an exception. If the purpose of an application is automated testing, and/or it's used as a quick-and-dirty internal tool as opposed to a product for an end user, this kind of exceptions is all you need to handle errors of almost all kinds. In some languages, you can even resume the execution from the point where the exception was raised after fixing the problem at the point where it was caught." Anyway, I generally avoid exceptions if they are not an obvious fit.
Apr 28 2012
On 28-04-2012 23:41, Timon Gehr wrote:On 04/28/2012 11:05 PM, q66 wrote:Nope. First of all, you'd have to declare the setter like this in D: property int foo(int v) { return x = v; } so that you can write: Next up is the issue of op-assign operations. In D, you can't do: obj.foo += 1; obj.foo++; -> set, etc).On Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:That is why they should be a narrow wrapper around a library defined type.On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote: [...]Besides AA literals, library can handle this JUST FINE.- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementationsOn the contrary, AA's are a major reason I started programming in D. In this day and age, it's simply inexcusable to *not* have some kind of hash type available by default.This sounds reasonable.Too large collection becomes too hard to manage. Separating it and distributing in style "you pay for what you use" is IMO the right approach.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for PerlUm... that's what a *library* is supposed to be: a large collection of useful stuff from which you can pick the few that you need right now.As I understand it, the 'agreed upon' design is that property int foo() { return x; } property void foo(int v) { x = v; } int foo { set{ x = value; }; get{ return x; } }The property crap. It's broken. If anything, it needs something like in- Properties - they're kinda broken at this point and the value is questionableWhat kind of properties are you referring to?I think it is even perfectly fine to just allow function calls without parentheses, but I wouldn't mind seeing that feature gone.-- - AlexWhy? Memory safety is generally considered to be important.They're far from necessary.- trusted systemThese are necessary.It can improve performance though, because the exceptional branches don't occur in the code that is normally executed.The exception handling system via try/catch is as bad and tedious as error codes, except the added runtime.- Exception handling - a lot of runtime, questionable valueI completely disagree. No exception handling means lots and lots and lots of boilerplate code for checking error codes, return values, which are too tedious to write, which translates to many people leaving them out and ending up with unreliable code that fail silently or crash outright when a function call they assumed would work stopped working. If you've worked in large multi-person projects, you'll see very quickly why you *need* exception handling. No modern language can do without exception handling. Maybe you have a beef with how it's currently done in D, but regardless, you *need* exception handling of some kind.It all roots from the idea "catch everything that throws". This is broken, as you DON'T always need to handle all sorts of errors (letting it segfault or something sometimes simply proves to be better than trying to save the situation;Except that it won't necessarily segfault. That is not how _reliable_ systems work. Robustness is an important property of critical systems. If your software might kill people if it behaves in the wrong way, you really really don't want to ignore error conditions.or you can simply assert it).Certainly, if it is a consistency criterion internal to the program, then assertions should be used.Also http://yosefk.com/c++fqa/exceptions.html#fqa-17.1 [snip.]The part of this article relevant for D is this: "Still, in many cases, the benefits of exceptions are more important than their problems. For example, if your language manages memory automatically, the problem of releasing acquired resources becomes a small one (you only have to care about files, etc., which are a tiny part of the "resources" used by a program - most of the "resources" are memory). If your language throws exceptions when you violate its rules (for example, upon out-of-bounds array access), these exceptions will help you find lots of bugs, especially if you can get the call stack from an exception. If the purpose of an application is automated testing, and/or it's used as a quick-and-dirty internal tool as opposed to a product for an end user, this kind of exceptions is all you need to handle errors of almost all kinds. In some languages, you can even resume the execution from the point where the exception was raised after fixing the problem at the point where it was caught." Anyway, I generally avoid exceptions if they are not an obvious fit.
Apr 29 2012
On 4/29/12, Alex R=F8nne Petersen <xtzgzorex gmail.com> wrote:Next up is the issue of op-assign operations. In D, you can't do: obj.foo +=3D 1; obj.foo++; -> set, etc).It's great to see another (successful) language implemented this. Do we have a proposal open for this somewhere?
Apr 29 2012
On 29-04-2012 22:16, Andrej Mitrovic wrote:On 4/29/12, Alex Rønne Petersen<xtzgzorex gmail.com> wrote:AFAIK no. -- - AlexNext up is the issue of op-assign operations. In D, you can't do: obj.foo += 1; obj.foo++; -> set, etc).It's great to see another (successful) language implemented this. Do we have a proposal open for this somewhere?
Apr 29 2012
On Sunday, 29 April 2012 at 20:16:16 UTC, Andrej Mitrovic wrote:On 4/29/12, Alex Rønne Petersen <xtzgzorex gmail.com> wrote:I believe DIP 4 is the proposal http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs But don't forget to check out DIP 5 too.Next up is the issue of op-assign operations. In D, you can't do: obj.foo += 1; obj.foo++; get -> inc -> set, etc).It's great to see another (successful) language implemented this. Do we have a proposal open for this somewhere?
Apr 29 2012
On 4/30/12, Jesse Phillips <jessekphillips+D gmail.com> wrote:I believe DIP 4 is the proposal http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs But don't forget to check out DIP 5 too.Well it says they're both superseeded by DIP 6 but DIP6 didn't implement things DIP4 was talking about.DIP4 goes on to discuss I didn't find anything in bugzilla, so I'm opening an enhancement request: http://d.puremagic.com/issues/show_bug.cgi?id=8006
Apr 29 2012
On 2012-04-29 22:16, Andrej Mitrovic wrote:On 4/29/12, Alex Rønne Petersen<xtzgzorex gmail.com> wrote:I think someone started to work on this. I have no idea what happened to it though. -- /Jacob CarlborgNext up is the issue of op-assign operations. In D, you can't do: obj.foo += 1; obj.foo++; -> set, etc).It's great to see another (successful) language implemented this. Do we have a proposal open for this somewhere?
Apr 30 2012
On 04/29/2012 10:03 PM, Alex Rønne Petersen wrote:On 28-04-2012 23:41, Timon Gehr wrote:I didn't say this was how it worked in the current compiler implementation. But I may be wrong on what is the design because I didn't take part in that discussion. Notably, read-update operations now work on the built-in length property of arrays. I don't think there is any justification for not implementing this for properties.As I understand it, the 'agreed upon' design is that property int foo() { return x; } property void foo(int v) { x = v; } int foo { set{ x = value; }; get{ return x; } }Nope. First of all, you'd have to declare the setter like this in D: property int foo(int v) { return x = v; } so that you can write: Next up is the issue of op-assign operations. In D, you can't do: obj.foo += 1; obj.foo++; -> set, etc).
Apr 29 2012
On 4/29/2012 6:05 AM, q66 wrote:Someone forgot to tell me how unusable they are, because I've been using them for years. Quite sensibly.I find versions sorta neat... and they're simple enough that they don't add to much bloat to the language. (Whereas if you added AND and OR to them, then they start duplicating the function of static if, and that's when they become redundant.)They're nearly unusable now. And the syntax simply makes no sense.T
Apr 28 2012
On Saturday, 28 April 2012 at 20:50:30 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 09:22:59PM +0200, q66 wrote:And the STL and libc isn't big? Size is only intimidating if you don't know what your looking for. Having to scour in std.ascii, then std.utf, then std.array or other locations when your looking for something can get a little annoying. But it's a learning curve, once you know it you tend to find the functions and information fairly quickly. More likely a good tutorial through the library would alleviate some of that, or just the parts that are more confusing. One part for example involving conversion for unicode, I still have no idea how to convert Latin1String (extended ascii) to utf so I could use all of phobos's power; So I've ended up writing my own little conversion function for that. It's going to come down that stuff we write and post up that we think is self explanatory isn't because as the implementers we understand it in intimately.- Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for PerlUm... that's what a *library* is supposed to be: a large collection of useful stuff from which you can pick the few that you need right now.
Apr 28 2012
On 2012-04-28 21:22, q66 wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:As others have said, I think this is crazy. -- /Jacob CarlborgAndrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- AAs integrated in the language; you barely ever use AA literals and having them purely in Phobos would help get rid of the runtime fat, as well as better implementations - Phobos is too fat - it needs to shrink to just a few core modules, others being distributed via some system like CPAN for Perl - Properties - they're kinda broken at this point and the value is questionable - trusted system - Exception handling - a lot of runtime, questionable value - Versions - not redundant, but needs a better system (with AND/OR, possibility of de-versioning, the assignment op to set versions is kinda bad) I think I would find some more, but these are the ones I can recall now.
Apr 29 2012
On 4/28/12, Walter Bright <newshound2 digitalmars.com> wrote:What's your list?I don't mind extra features, just as long as they're properly documented and implemented. For example, I have absolutely no uses for anonymous classes right now, but I know DWT2 uses them and probably other people do use them. Personally I find the hardest threads to to follow are the ones discussing in/out/inout/autoref. For one thing there are compiler bugs, but then there are misconceptions between what developers vs documentation vs core devs say about them. And then you mix in classes and templates into the story and it all becomes a large forest of information that is very hard to digest. Another feature I'm curious about is .dup/.idup. It's basically hardcoded for a couple of types, but why not instead use UFCS and implement .dup/.idup in std.array as a free function? Then you might even use it for user-types by requiring a type to implement .dup/.idup functions. Also there's mixin templates. What exactly is the difference between mixin templates and regular templates? We can use the mixin statement for both types right now, so there doesn't seem to be a distinction. For example, if you take samples from the template mixin page (http://dlang.org/template-mixin.html) and you remove "mixin" from the template declaration, all of the samples will continue to work. You could remove this declaration feature right now and you probably wouldn't break any code at all. Seems like low-hanging fruit to me.
Apr 28 2012
On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:Also there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.
Apr 28 2012
On 4/28/12, Walter Bright <newshound2 digitalmars.com> wrote:A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point.Ooooh. Suddenly that explains some of my compilation errors.
Apr 28 2012
On 04/28/2012 10:02 PM, Walter Bright wrote:On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:The implementation seems to disagree: int x; template X(){ // not a mixin template void y(){x=2;} } class C{ int x; mixin X; // picks up local 'x' } void main(){ auto c = new C; c.y(); import std.stdio; writeln(x," ",c.x); // "0 2" } Or am I misunderstanding your statement?Also there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.
Apr 28 2012
On 4/28/2012 1:32 PM, Timon Gehr wrote:On 04/28/2012 10:02 PM, Walter Bright wrote:Makes it a mixin template.On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:The implementation seems to disagree: int x; template X(){ // not a mixin template void y(){x=2;} } class C{ int x; mixin X; // picks up local 'x'Also there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.} void main(){ auto c = new C; c.y(); import std.stdio; writeln(x," ",c.x); // "0 2" } Or am I misunderstanding your statement?The behavior is as I described.
Apr 30 2012
On Tuesday, 1 May 2012 at 02:40:34 UTC, Walter Bright wrote:On 4/28/2012 1:32 PM, Timon Gehr wrote:Why not just require mixin templates to be declared using »mixin template« then? David[…] class C{ int x; mixin X; // picks up local 'x'Makes it a mixin template.
Apr 30 2012
On 04/28/12 22:02, Walter Bright wrote:On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:Yeah, but this was actually the only suggestion so far in this thread that i could agree with... The issue is template t1() { int a = b; } int main() { int b; mixin t1; return a; } which is currently accepted - and would enforcing the mixin annotation really help anything? arturAlso there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.
Apr 28 2012
On Sat, 28 Apr 2012 22:40:10 +0200, Artur Skawina <art.08.09 gmail.com> wrote:On 04/28/12 22:02, Walter Bright wrote:At least some of us want mixin templates to be marked mixin at declaration point, and usable without 'mixin': mixin template A( ) { int n; } struct S { A!(); }On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:Yeah, but this was actually the only suggestion so far in this thread that i could agree with... The issue is template t1() { int a = b; } int main() { int b; mixin t1; return a; } which is currently accepted - and would enforcing the mixin annotation really help anything? arturAlso there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.
Apr 29 2012
On 04/30/12 02:33, Simen Kjaeraas wrote:On Sat, 28 Apr 2012 22:40:10 +0200, Artur Skawina <art.08.09 gmail.com> wrote:Yes, that's the other possible use for marking a template as a mixin. Unlike my above example it wouldn't then be redundant; the question is however if this functionality really is desirable... mixin template t1() { auto _ = a = b; } int main() { int a, b=1; t1!(); return a; } This program would now return '1', which can be non-obvious if you don't know the definition of 't1'. Right now you have to write that as template t1() { auto _ = a = b; } int main() { int a, b=1; mixin t1!(); return a; } so the mixin is clearly visible. These kind of template macros would be useful and i'd like to have them too, but there is a cost, and i'm not yet sure that being able to omit the 'mixin' keyword would be worth it. arturOn 04/28/12 22:02, Walter Bright wrote:At least some of us want mixin templates to be marked mixin at declaration point, and usable without 'mixin': mixin template A( ) { int n; } struct S { A!(); }On 4/28/2012 12:36 PM, Andrej Mitrovic wrote:Yeah, but this was actually the only suggestion so far in this thread that i could agree with... The issue is template t1() { int a = b; } int main() { int b; mixin t1; return a; } which is currently accepted - and would enforcing the mixin annotation really help anything? arturAlso there's mixin templates. What exactly is the difference between mixin templates and regular templates?A mixin template is instantiated in context of the instantiation point, while a regular template is instantiated in the context of the template definition point. This becomes relevant when looking up symbols that are not defined within the template.
Apr 29 2012
On 2012-04-28 21:36, Andrej Mitrovic wrote:On 4/28/12, Walter Bright<newshound2 digitalmars.com> wrote:If a anonymous classes where remove from D, life would get even harder for DWT.What's your list?I don't mind extra features, just as long as they're properly documented and implemented. For example, I have absolutely no uses for anonymous classes right now, but I know DWT2 uses them and probably other people do use them.Personally I find the hardest threads to to follow are the ones discussing in/out/inout/autoref. For one thing there are compiler bugs, but then there are misconceptions between what developers vs documentation vs core devs say about them. And then you mix in classes and templates into the story and it all becomes a large forest of information that is very hard to digest.Agree.Another feature I'm curious about is .dup/.idup. It's basically hardcoded for a couple of types, but why not instead use UFCS and implement .dup/.idup in std.array as a free function? Then you might even use it for user-types by requiring a type to implement .dup/.idup functions.Agree with this one as well. -- /Jacob Carlborg
Apr 29 2012
On Sun, Apr 29, 2012 at 04:43:12PM +0200, Jacob Carlborg wrote:On 2012-04-28 21:36, Andrej Mitrovic wrote:[...][...] +1. This would make generic code easier to write. Which is good, because the less we have to rewrite code that's been written a hundred times in the past already, the better. T -- A linguistics professor was lecturing to his class one day. "In English," he said, "A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative." A voice from the back of the room piped up, "Yeah, yeah."Another feature I'm curious about is .dup/.idup. It's basically hardcoded for a couple of types, but why not instead use UFCS and implement .dup/.idup in std.array as a free function? Then you might even use it for user-types by requiring a type to implement .dup/.idup functions.Agree with this one as well.
Apr 29 2012
On 28-04-2012 21:36, Andrej Mitrovic wrote:On 4/28/12, Walter Bright<newshound2 digitalmars.com> wrote:I use them too. They're useful if you have an abstract method that just needs to return an arbitrary object implementing some interface or whatever.What's your list?I don't mind extra features, just as long as they're properly documented and implemented. For example, I have absolutely no uses for anonymous classes right now, but I know DWT2 uses them and probably other people do use them.Personally I find the hardest threads to to follow are the ones discussing in/out/inout/autoref. For one thing there are compiler bugs, but then there are misconceptions between what developers vs documentation vs core devs say about them. And then you mix in classes and templates into the story and it all becomes a large forest of information that is very hard to digest. Another feature I'm curious about is .dup/.idup. It's basically hardcoded for a couple of types, but why not instead use UFCS and implement .dup/.idup in std.array as a free function? Then you might even use it for user-types by requiring a type to implement .dup/.idup functions.This seems reasonable to me.Also there's mixin templates. What exactly is the difference between mixin templates and regular templates? We can use the mixin statement for both types right now, so there doesn't seem to be a distinction. For example, if you take samples from the template mixin page (http://dlang.org/template-mixin.html) and you remove "mixin" from the template declaration, all of the samples will continue to work. You could remove this declaration feature right now and you probably wouldn't break any code at all. Seems like low-hanging fruit to me.-- - Alex
Apr 29 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse). This is nothing more than a fancy function with a delegate parameter. * enum - enum should be completely redesigned to only implement what it's named after: enumerations. * version - this does not belong in a programming language. Git is a much better solution. * di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax. It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons. This would reduce the size of the language to half of its current size, maybe even more.
Apr 28 2012
On 04/28/2012 09:58 PM, foobar wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).This is nothing more than a fancy function with a delegate parameter.That would be opApply.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 28 2012
On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:On 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyThis is nothing more than a fancy function with a delegate parameter.That would be opApply.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain and on the other hand it doesn't provide properly encapsulated enums such as for instance the Java 5.0 ones or the functional kind.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.This includes __traits, templates, static ifs, etc..* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?No I'm joking. The current system is a pile of hacks on top of the broken model of c++ templates. I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times. This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 28 2012
On Saturday, 28 April 2012 at 23:25:10 UTC, foobar wrote:On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:Well, it's your opinion. But I bet it's not the opinion of designers, and I even believe they wanted to add foreach in C++ (or is it already the case ?). Putting things in the library isn't the solution for everything: it's often hard (if possible) to make it work as well as in the core language, and error messages are usually more cryptic. Basic features like this should stay in the core language in my opinion.On 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).No it isn't. Ask the kernel hackers why they still use #ifdef instead of using hundreds of git branches for every feature and platform they must maintain.Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyThis is nothing more than a fancy function with a delegate parameter.That would be opApply.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain and on the other hand it doesn't provide properly encapsulated enums such as for instance the Java 5.0 ones or the functional kind.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.You should use Go. It fits better to your views about programming languages than D.This includes __traits, templates, static ifs, etc..* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?No I'm joking. The current system is a pile of hacks on top of the broken model of c++ templates. I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times. This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 28 2012
On 29-04-2012 01:49, SomeDude wrote:On Saturday, 28 April 2012 at 23:25:10 UTC, foobar wrote:C++11 has range-based for (which is basically foreach).On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:Well, it's your opinion. But I bet it's not the opinion of thousands of believe they wanted to add foreach in C++ (or is it already the case ?). Putting things in the library isn't the solution for everything: it's often hard (if possible) to make it work as well as in the core language, and error messages are usually more cryptic. Basic features like this should stay in the core language in my opinion.On 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).-- - AlexNo it isn't. Ask the kernel hackers why they still use #ifdef instead of using hundreds of git branches for every feature and platform they must maintain.Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyThis is nothing more than a fancy function with a delegate parameter.That would be opApply.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain and on the other hand it doesn't provide properly encapsulated enums such as for instance the Java 5.0 ones or the functional kind.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.You should use Go. It fits better to your views about programming languages than D.This includes __traits, templates, static ifs, etc..* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?No I'm joking. The current system is a pile of hacks on top of the broken model of c++ templates. I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times. This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 29 2012
On Sunday, 29 April 2012 at 20:10:20 UTC, Alex Rønne Petersen wrote:On 29-04-2012 01:49, SomeDude wrote:This is off-topic, but in general, please try to quote only the relevant parts of the message you are replying to (you just quoted the whole long message three times in full). David[snip wall of text]C++11 has range-based for (which is basically foreach).[snip wall of text]
Apr 29 2012
On Saturday, 28 April 2012 at 23:25:10 UTC, foobar wrote:On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:Aren't both of those just side effects of bad design? Most #ifdef calls were to overcome limits in the language that probably overloading would have resolved. I haven't done large projects code beyond my own, and the one or two I've seen were actually done in java. All Architecture and OS specific code should be hopefully done in just one file; That way ugly or special purpose code could be limited to one spot. Not only that but the rest of the code should be clean and you can build another architecture or system with minimal work. Course there will be cases where a lot of work would be needed, or in other cases no work at all.On 04/28/2012 09:58 PM, foobar wrote:It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.
Apr 28 2012
On 29.04.2012 3:25, foobar wrote:On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:C++ was criticized for a long time for NOT having foreach in the language. Now they have http://www2.research.att.com/~bs/C++0xFAQ.html#for. Also people were so desperate to gave it that even this http://www.boost.org/doc/libs/1_49_0/doc/html/foreach.html was considered a nice addition to boost (and still part of it). Obviously somehow you want to go into the opposite direction. Beats me. -- Dmitry OlshanskyOn 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).
Apr 28 2012
My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).C++ was criticized for a long time for NOT having foreach in the language. Now they have http://www2.research.att.com/~bs/C++0xFAQ.html#for. Also people were so desperate to gave it that even this http://www.boost.org/doc/libs/1_49_0/doc/html/foreach.html was considered a nice addition to boost (and still part of it). Obviously somehow you want to go into the opposite direction. Beats me.If it simplifies code, makes it easier, and is more consistent, having it is better than not having it. Like walter said in one of the recent videos (going native 2012) regarding having an assembler in a language: 'When you need it, you got to have it'. True most features can be re-written as work arounds, but if you don't have to then why insist on it? Backtracking by removing key features which make the language pleasant may throw us back into the C and C++ days. Yes you can do full memory management yourself, and use pointers and pass it's size to functions. We have fat pointers, so why insist on backtracking? At the worst case if it isn't breaking the language leave it alone. If you have good reasons for it, explain them in detail. At best those of us who know better will laugh and move on.
Apr 28 2012
On Sunday, 29 April 2012 at 06:11:00 UTC, Era Scarecrow wrote:One of the ideas that I see regularly thrown around is to remove more and more things from the core language and put them in the libraries, because it's possible, and it would make for a thinner languages. Well, these are good reasons to do it, but there are many good reasons NOT to do it. Some general reasons: 1. code is uglier when in the libraries. One must add imports, and template code is uglier and harder to write than plain old code. 2. template code makes bigger size executables 3. error messages are more cryptic 4. we like to think that putting things in the library helps changing things easier, but my opinion is, changing fundamental structures in the standard library may actually break more code than changing them in the core language, because of the heavy interplay between modules, and also because the standard library is probably less well tested (in terms of number of regression tests) than the core language. 5. it makes work much harder for tools and parsers Specific to D: 6. my impression is, from what I've seen in Bugzilla, that Phobos bugs tend to stay around longer, because there is not enough workforce on it These a lot of drawbacks in my opinion. Basically, one of the main reasons the D code is clean, is because the core languages features so many useful things, with a nice, clean syntax. Moving them to the standard library will automatically make the code uglier and the language harder to use.My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).C++ was criticized for a long time for NOT having foreach in the language. Now they have http://www2.research.att.com/~bs/C++0xFAQ.html#for. Also people were so desperate to gave it that even this http://www.boost.org/doc/libs/1_49_0/doc/html/foreach.html was considered a nice addition to boost (and still part of it). Obviously somehow you want to go into the opposite direction. Beats me.If it simplifies code, makes it easier, and is more consistent, having it is better than not having it. Like walter said in one of the recent videos (going native 2012) regarding having an assembler in a language: 'When you need it, you got to have it'. True most features can be re-written as work arounds, but if you don't have to then why insist on it? Backtracking by removing key features which make the language pleasant may throw us back into the C and C++ days. Yes you can do full memory management yourself, and use pointers and pass it's size to functions. We have fat pointers, so why insist on backtracking? At the worst case if it isn't breaking the language leave it alone. If you have good reasons for it, explain them in detail. At best those of us who know better will laugh and move on.
Apr 29 2012
On 04/29/2012 01:25 AM, foobar wrote:On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:Therefore you say that it is not useful as a language feature.On 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).Well, I don't think this is better than built-in foreach (with full break and continue and goto even for user-defined opApply!)Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyThis is nothing more than a fancy function with a delegate parameter.That would be opApply.I think that is actually not true. It might have been the original motivation, but it has gone beyond that. Which weaknesses in particular? I don't think that the toolchain can be improved in any way in this regard.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?and on the other hand it doesn't provide properly encapsulated enumsThose could in theory be added without removing the manifest constant usage.such as for instance the Java 5.0 ones or the functional kind.An algebraic data type is not an 'enumeration', so this is a moot point.Which projects you are aware of actually use this kind of versioning?It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.This is what makes D useful to me.This includes __traits, templates, static ifs, etc..* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?Examples in concrete syntax? How would you replace eg. string mixin functionality?No I'm joking. The current system is a pile of hacks on top of the broken model of c++ templates. I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It is not. For example, code that is only executed during CTFE does never have to behave gracefully if the input is ill-formed.
Apr 29 2012
On Sunday, 29 April 2012 at 08:58:24 UTC, Timon Gehr wrote:I think we reached a matter of taste here. How often do you use these features anyway in your regular code? I prefer a more functional style with higher order functions (map/reduce/filter/etc..) so for me foreach is about applying something to all elements and doesn't entail usage of break/continue/etc.. I'll use these constructs in a for loop but not a foreach loop.[...] Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyWell, I don't think this is better than built-in foreach (with full break and continue and goto even for user-defined opApply!)The weakness as far as I know is about link time optimization of constants. But regardless, my ideal implementation of so called "compile-time" features, including compile time constants, would be very different anyway.I think that is actually not true. It might have been the original motivation, but it has gone beyond that. Which weaknesses in particular? I don't think that the toolchain can be improved in any way in this regard.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?I disagree. They are a generalization of the concept. In fact, functional languages such as ML implement c style enums as an algebraic data type.and on the other hand it doesn't provide properly encapsulated enumsThose could in theory be added without removing the manifest constant usage.such as for instance the Java 5.0 ones or the functional kind.An algebraic data type is not an 'enumeration', so this is a moot point.I disagree - you should make sure the input is valid or all sorts of bad things could potentially happen such as a compiler can get stuck in an infinite loop. If you only use a batch mode compiler you can simply kill the process which btw applies just the same to your user program. However, if you use an integrated compiler in your IDE that could cause me to lose part of my work if the IDE crashes.[...] I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times.Examples in concrete syntax? How would you replace eg. string mixin functionality?This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It is not. For example, code that is only executed during CTFE does never have to behave gracefully if the input is ill-formed.
Apr 29 2012
On 04/29/2012 11:31 AM, foobar wrote:On Sunday, 29 April 2012 at 08:58:24 UTC, Timon Gehr wrote:Certainly, and this applies to the other issues as well.I think we reached a matter of taste here.[...] Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyWell, I don't think this is better than built-in foreach (with full break and continue and goto even for user-defined opApply!)How often do you use these features anyway in your regular code?Not too often, but it is awesome that it actually works. ;)I prefer a more functional style with higher order functions (map/reduce/filter/etc..) so for me foreach is about applying something to all elements and doesn't entail usage of break/continue/etc..Some algorithms are better expressed in functional terms, some algorithms are better expressed in imperative terms. I think a combination of the two usually is the best choice.I'll use these constructs in a for loop but not a foreach loop.break can be used as an optimisation to stop execution of a loop that performs a 'reduce' if the result cannot change after a certain point. I use continue mostly for 'filter'-ing out elements from consideration. Usually there is not a huge difference between imperative style and functional style loops.Well, you never elaborate on these things. BTW, what is your stance on template haskell?The weakness as far as I know is about link time optimization of constants. But regardless, my ideal implementation of so called "compile-time" features, including compile time constants, would be very different anyway.I think that is actually not true. It might have been the original motivation, but it has gone beyond that. Which weaknesses in particular? I don't think that the toolchain can be improved in any way in this regard.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?The current way enums can be used as manifest constants is a generalization as well. The generalization takes place on the static semantics level instead of on the conceptual level though.I disagree. They are a generalization of the concept. In fact, functional languages such as ML implement c style enums as an algebraic data type.and on the other hand it doesn't provide properly encapsulated enumsThose could in theory be added without removing the manifest constant usage.such as for instance the Java 5.0 ones or the functional kind.An algebraic data type is not an 'enumeration', so this is a moot point.?[...] I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times.Examples in concrete syntax? How would you replace eg. string mixin functionality?It could fail in a number of other ways. I don't think that this example can be used to invalidate the statement.I disagree - you should make sure the input is valid or all sorts of bad things could potentially happen such as a compiler can get stuck in an infinite loop.This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It is not. For example, code that is only executed during CTFE does never have to behave gracefully if the input is ill-formed.If you only use a batch mode compiler you can simply kill the process which btw applies just the same to your user program.Maybe the user program should not be killed. See your IDE example.However, if you use an integrated compiler in your IDE that could cause me to lose part of my work if the IDE crashes.Why would the IDE crash?
Apr 29 2012
On Sunday, 29 April 2012 at 11:23:17 UTC, Timon Gehr wrote:On 04/29/2012 11:31 AM, foobar wrote:I agree and indeed I haven't argued to remove break/continue from the language. Imperative style loops are already expressible with for/while/etc where break/continue work as advertizes. IMO a foreach loop is a higher level concept more suitable for functional style loops. In any case, break/continue is implemented via opApply's return values and as such doesn't require anything special from the compiler to implement a library based foreach.On Sunday, 29 April 2012 at 08:58:24 UTC, Timon Gehr wrote:Certainly, and this applies to the other issues as well.I think we reached a matter of taste here.[...] Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyWell, I don't think this is better than built-in foreach (with full break and continue and goto even for user-defined opApply!)How often do you use these features anyway in your regular code?Not too often, but it is awesome that it actually works. ;)I prefer a more functional style with higher order functions (map/reduce/filter/etc..) so for me foreach is about applying something to all elements and doesn't entail usage of break/continue/etc..Some algorithms are better expressed in functional terms, some algorithms are better expressed in imperative terms. I think a combination of the two usually is the best choice.Well, I'll use a filter to filter out elements.... :)I'll use these constructs in a for loop but not a foreach loop.break can be used as an optimisation to stop execution of a loop that performs a 'reduce' if the result cannot change after a certain point. I use continue mostly for 'filter'-ing out elements from consideration.Usually there is not a huge difference between imperative style and functional style loops.I discussed this many times in the past... I don't really know haskell. But I do like ML.Well, you never elaborate on these things. BTW, what is your stance on template haskell?The weakness as far as I know is about link time optimization of constants. But regardless, my ideal implementation of so called "compile-time" features, including compile time constants, would be very different anyway.I think that is actually not true. It might have been the original motivation, but it has gone beyond that. Which weaknesses in particular? I don't think that the toolchain can be improved in any way in this regard.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?A language is the interface between a human programmer and a computer and should IMO provide clear conceptual level abstractions for the benefit of the human. I realize that using enum for manifest constants makes sense on the implementation level but I feel the compiler should work for me and not the other way around.The current way enums can be used as manifest constants is a generalization as well. The generalization takes place on the static semantics level instead of on the conceptual level though.I disagree. They are a generalization of the concept. In fact, functional languages such as ML implement c style enums as an algebraic data type.and on the other hand it doesn't provide properly encapsulated enumsThose could in theory be added without removing the manifest constant usage.such as for instance the Java 5.0 ones or the functional kind.An algebraic data type is not an 'enumeration', so this is a moot point.macro testMacro() { std.writeln("Hello world!"); <| std.writeln("Hello world!"); |> } macro is a syntactic sugar on top of a regular function. You can call it just like you call a regular function. The first line is executed regularly and the second one is mixed-in [returned token stream from the macro] since the macro is evaluated by the compiler, the first line would generate compile-time output. the second line would be part of the generated code and would be thus executed during run-time of my code. Regarding syntax, the main difference is that it's a token stream and not text but otherwise pretty much the same as current CTFE. The important difference here is the execution model which is different from CTFE.?[...] I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times.Examples in concrete syntax? How would you replace eg. string mixin functionality?My example illustrates that the same considerations should be given to "compile-time" code as well as to the client application and it all depends on what you're trying to achieve.It could fail in a number of other ways. I don't think that this example can be used to invalidate the statement.I disagree - you should make sure the input is valid or all sorts of bad things could potentially happen such as a compiler can get stuck in an infinite loop.This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It is not. For example, code that is only executed during CTFE does never have to behave gracefully if the input is ill-formed.If you only use a batch mode compiler you can simply kill the process which btw applies just the same to your user program.Maybe the user program should not be killed. See your IDE example.However, if you use an integrated compiler in your IDE that could cause me to lose part of my work if the IDE crashes.Why would the IDE crash?
Apr 29 2012
On 04/29/2012 02:17 PM, foobar wrote:On Sunday, 29 April 2012 at 11:23:17 UTC, Timon Gehr wrote:The filter condition is not always conveniently expressed in terms of a lambda function.break can be used as an optimisation to stop execution of a loop that performs a 'reduce' if the result cannot change after a certain point. I use continue mostly for 'filter'-ing out elements from consideration.Well, I'll use a filter to filter out elements.... :)Well, I don't think that 'enum' for manifest constants asks a lot from the programmer, but YMMV.... The current way enums can be used as manifest constants is a generalization as well. The generalization takes place on the static semantics level instead of on the conceptual level though.A language is the interface between a human programmer and a computer and should IMO provide clear conceptual level abstractions for the benefit of the human. I realize that using enum for manifest constants makes sense on the implementation level but I feel the compiler should work for me and not the other way around.... macro testMacro() { std.writeln("Hello world!"); <| std.writeln("Hello world!"); |> } macro is a syntactic sugar on top of a regular function. You can call it just like you call a regular function. The first line is executed regularly and the second one is mixed-in [returned token stream from the macro] since the macro is evaluated by the compiler, the first line would generate compile-time output. the second line would be part of the generated code and would be thus executed during run-time of my code. Regarding syntax, the main difference is that it's a token stream and not text but otherwise pretty much the same as current CTFE. The important difference here is the execution model which is different from CTFE.We have the 'macro' keyword ;). Probably it should just be a built-in primitive type of the language that represents an AST?
Apr 29 2012
On Sun, Apr 29, 2012 at 01:23:17PM +0200, Timon Gehr wrote:On 04/29/2012 11:31 AM, foobar wrote:[...]On Sunday, 29 April 2012 at 08:58:24 UTC, Timon Gehr wrote:Like if the Ackermann function was evaluated in CTFE for very large arguments. Technically it isn't an infinite loop, but you probably wouldn't like the results. T -- If I were two-faced, would I be wearing this one? -- Abraham LincolnIt could fail in a number of other ways. I don't think that this example can be used to invalidate the statement.It is not. For example, code that is only executed during CTFE does never have to behave gracefully if the input is ill-formed.I disagree - you should make sure the input is valid or all sorts of bad things could potentially happen such as a compiler can get stuck in an infinite loop.
Apr 29 2012
On 29-04-2012 01:25, foobar wrote:On Saturday, 28 April 2012 at 20:43:38 UTC, Timon Gehr wrote:Yeah, we tried that in C++. It sucked. The reason it works for many functional languages is that they have even more terse syntax than D. It would suck to make foreach a function in D.On 04/28/2012 09:58 PM, foobar wrote:I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).Yeah, we tried that in C and C++. It sucked. See: Autotools.Indeed but I'd go even further by integrating it with ranges so that ranges would provide an opApply like method e.g. auto r = BinaryTree!T.preOrder(); // returns range r.each( (T elem) { ...use elem...}); // each method a-la RubyThis is nothing more than a fancy function with a delegate parameter.That would be opApply.On the one hand the current enum for manifest constants is a hack due to weaknesses of the toolchain and on the other hand it doesn't provide properly encapsulated enums such as for instance the Java 5.0 ones or the functional kind.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.-- - AlexThis includes __traits, templates, static ifs, etc..* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?No I'm joking. The current system is a pile of hacks on top of the broken model of c++ templates. I should be able to use a *very* minimalistic system to write completely _regular_ D code and run it at different times. This is a simple matter of separation of concerns: what we want to execute (what code) is separate to the concern of when we want to execute it.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 29 2012
Meta comment: C++ is the spawn of the devil so I don't accept anything related to c++ as a valid argument. On Sunday, 29 April 2012 at 20:09:34 UTC, Alex Rønne Petersen wrote: [...]See meta comment above.I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.Yeah, we tried that in C++. It sucked.The reason it works for many functional languages is that they have even more terse syntax than D. It would suck to make foreach a function in D.D wants to support functional programming. That means we should provide whatever is necessary to write functional style code including foreach methods. IF D can't properly implement a FP foreach method (And IMO it *can*) than we have failed.see meta comment above. The fact that you used a horribly designed language with a horrible mess of a "build tool" made out of shell scripts IIRC is not an indication that the language should include build-tool functionality.Yeah, we tried that in C and C++. It sucked. See: Autotools.It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.
Apr 30 2012
On 30-04-2012 12:18, foobar wrote:Meta comment: C++ is the spawn of the devil so I don't accept anything related to c++ as a valid argument. On Sunday, 29 April 2012 at 20:09:34 UTC, Alex Rønne Petersen wrote: [...]Of course it can, but not with type inference, unless you templatize it. That is: void forEach(alias fun, R)(R range) { // ... } enjoys type inference: forEach!(item => foo(item))(myRange); But this doesn't: void forEach(R)(R range, scope void delegate(ElementType!R) dg) { // ... } This won't work: forEach(myRange, item => foo(item)); You have to do: forEach(myRange, (ElementType!(typeof(myRange)) => foo(item)); which, frankly, sucks.See meta comment above.I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.Yeah, we tried that in C++. It sucked.The reason it works for many functional languages is that they have even more terse syntax than D. It would suck to make foreach a function in D.D wants to support functional programming. That means we should provide whatever is necessary to write functional style code including foreach methods. IF D can't properly implement a FP foreach method (And IMO it *can*) than we have failed.-- - Alexsee meta comment above. The fact that you used a horribly designed language with a horrible mess of a "build tool" made out of shell scripts IIRC is not an indication that the language should include build-tool functionality.Yeah, we tried that in C and C++. It sucked. See: Autotools.It is far better than having a pile of #ifdef styled spaghetti code. I'd expect to have all the OS specific code encapsulated separately anyway, not spread around the code base. Which is the current recommended way of using versions anyway. The inevitable conclusion would be to either use a version management system like git or have separate implementation modules for platform specific code and use the build tool to implement the logic of select the modules to include in the build.* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.
Apr 30 2012
On 04/30/2012 05:13 PM, Alex Rønne Petersen wrote:On 30-04-2012 12:18, foobar wrote:I agree. It is due to the fact that currently actually no inference takes place, it is just simple deduction. It shouldn't be very hard to add that functionality.Meta comment: C++ is the spawn of the devil so I don't accept anything related to c++ as a valid argument. On Sunday, 29 April 2012 at 20:09:34 UTC, Alex Rønne Petersen wrote: [...]Of course it can, but not with type inference, unless you templatize it. That is: void forEach(alias fun, R)(R range) { // ... } enjoys type inference: forEach!(item => foo(item))(myRange); But this doesn't: void forEach(R)(R range, scope void delegate(ElementType!R) dg) { // ... } This won't work: forEach(myRange, item => foo(item)); You have to do: forEach(myRange, (ElementType!(typeof(myRange)) => foo(item)); which, frankly, sucks.See meta comment above.I have used D and didn't claim that foreach isn't useful. What I said that is that it belongs in the library, NOT the language.Yeah, we tried that in C++. It sucked.The reason it works for many functional languages is that they have even more terse syntax than D. It would suck to make foreach a function in D.D wants to support functional programming. That means we should provide whatever is necessary to write functional style code including foreach methods. IF D can't properly implement a FP foreach method (And IMO it *can*) than we have failed.
Apr 30 2012
On 2012-04-28 22:43, Timon Gehr wrote:On 04/28/2012 09:58 PM, foobar wrote:Have a look at what Scala have done. They basically have the complete compiler available as a library. Then they used this library to implement runtime reflection and macros. Macros in Scala are functions that execute at compile time. -- /Jacob CarlborgIt should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?
Apr 29 2012
On 04/29/2012 04:53 PM, Jacob Carlborg wrote:On 2012-04-28 22:43, Timon Gehr wrote:It is not as powerful as what we have in D and it requires invoking the compiler multiple times.On 04/28/2012 09:58 PM, foobar wrote:Have a look at what Scala have done. They basically have the complete compiler available as a library. Then they used this library to implement runtime reflection and macros. Macros in Scala are functions that execute at compile time.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?
Apr 29 2012
On 2012-04-29 18:28, Timon Gehr wrote:On 04/29/2012 04:53 PM, Jacob Carlborg wrote:That's the whole point, there won't be any special case for CTFE. BTW, isn't that basically the same as having a built-in interpreter? -- /Jacob CarlborgOn 2012-04-28 22:43, Timon Gehr wrote:It is not as powerful as what we have in D and it requires invoking the compiler multiple times.On 04/28/2012 09:58 PM, foobar wrote:Have a look at what Scala have done. They basically have the complete compiler available as a library. Then they used this library to implement runtime reflection and macros. Macros in Scala are functions that execute at compile time.It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?
Apr 29 2012
On 28-04-2012 22:43, Timon Gehr wrote:On 04/28/2012 09:58 PM, foobar wrote:Removing it would be craziness.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:foreach is very useful. Have you actually used D?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse).That is absolutely horrible. It's not how branches are meant to be used.This is nothing more than a fancy function with a delegate parameter.That would be opApply.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.What is the benefit?* version - this does not belong in a programming language. Git is a much better solution.So you'd maintain a git branch for every OS if there is some small part that is OS-dependent? I don't think that is a better approach at all.-- - Alex* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago. * This is a big one: get rid of *all* current compile time special syntax.What would that be exactly?It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons.Are you serious?This would reduce the size of the language to half of its current size, maybe even more.I am certain that it would not. You missed to present the 'general purpose mechanisms'.
Apr 29 2012
On Sat, Apr 28, 2012 at 09:58:02PM +0200, foobar wrote: [...]D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse). This is nothing more than a fancy function with a delegate parameter.I disagree. Having a dedicated foreach construct allows the compiler to optimize away the delegate in certain cases. I wouldn't want to incur the cost of creating and passing a delegate in something as simple as foreach (i; 0..100), for example.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.Actually, I rather like the enum idiom of declaring compile-time constants. Though it could do with a renaming to something more befitting.* version - this does not belong in a programming language. Git is a much better solution.This is an interesting idea. But using separate git branches just for having versioned code seems a bit like total overkill... plus a maintenance nightmare since you have to continue pull and merge changes to every porting branch every time development happens. Whereas having everything represented in source means that whoever writes a new feature is also responsible for making it work with whatever versions are currently out there. After-the-fact fixes are always painful.* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I proposed a while ago that .di files should be replaced by something better: omit ALL function bodies, template bodies, private members, etc., and just keep the "real" public API in the human-readable part of the file. Function and template bodies should be kept in as a binary blob readable by the compiler (which obviously needs to know them otherwise it won't be able to expand templates). (Yes the binary blob can be reverse-engineered, but so can executables, so it's a moot point. We're not trying to write cryptographic security here, but it's nice to separate what the compiler needs to know vs. what the user of a library needs to know.)* This is a big one: get rid of *all* current compile time special syntax. It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons. This would reduce the size of the language to half of its current size, maybe even more.I have to disagree here. CTFE and compile-time features is a major reason I like D. I argue rather that compile-time features should be *improved*. The current situation is good, but not quite there yet. It can be made better. T -- Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
Apr 28 2012
On Saturday, 28 April 2012 at 21:02:25 UTC, H. S. Teoh wrote:[...] I disagree. Having a dedicated foreach construct allows the compiler to optimize away the delegate in certain cases. I wouldn't want to incur the cost of creating and passing a delegate in something as simple as foreach (i; 0..100), for example.compiler inlining? There is no reason why this should be special cased for a specific redundant construct in the language. Shouldn't I enjoy similar optimization techniques when using other kinds of functions with delegate parameters?I agree with the general notion here. Whatever the actual implementation details are, the API should be strongly tied to the binary in order to insure consistency and ease of use. I shouldn't need to worry if the header files match the binary library. Regarding the human readable API - that's why we have documentation for.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.Actually, I rather like the enum idiom of declaring compile-time constants. Though it could do with a renaming to something more befitting.* version - this does not belong in a programming language. Git is a much better solution.This is an interesting idea. But using separate git branches just for having versioned code seems a bit like total overkill... plus a maintenance nightmare since you have to continue pull and merge changes to every porting branch every time development happens. Whereas having everything represented in source means that whoever writes a new feature is also responsible for making it work with whatever versions are currently out there. After-the-fact fixes are always painful.* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I proposed a while ago that .di files should be replaced by something better: omit ALL function bodies, template bodies, private members, etc., and just keep the "real" public API in the human-readable part of the file. Function and template bodies should be kept in as a binary blob readable by the compiler (which obviously needs to know them otherwise it won't be able to expand templates). (Yes the binary blob can be reverse-engineered, but so can executables, so it's a moot point. We're not trying to write cryptographic security here, but it's nice to separate what the compiler needs to know vs. what the user of a library needs to know.)Please see my other reply to Timor. "compile-time" is simply the run-time of the compiler and shouldn't require any special syntax. E.g. D currently requires me to use pragma to output a message during compilation whereas I think it would be much cleaner to simply use writeln() in a component loaded and run by the compiler during compilation of my target code.* This is a big one: get rid of *all* current compile time special syntax. It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons. This would reduce the size of the language to half of its current size, maybe even more.I have to disagree here. CTFE and compile-time features is a major reason I like D. I argue rather that compile-time features should be *improved*. The current situation is good, but not quite there yet. It can be made better. T
Apr 28 2012
On Saturday, 28 April 2012 at 23:50:22 UTC, foobar wrote:On Saturday, 28 April 2012 at 21:02:25 UTC, H. S. Teoh wrote:* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I agree with the general notion here. Whatever the actual implementation details are, the API should be strongly tied to the binary in order to insure consistency and ease of use. I shouldn't need to worry if the header files match the binary library. Regarding the human readable API - that's why we have documentation for.Mmm well the main reason I see using .di files, is cases when the input library/file/dll doesn't give you much or any information. like... most dll's today. There's also tools to strip that extra debugging and structure information from your output file, so if you distribute a binary only, you still need to include it's .h file or .di file. Cases where this would be far more relevant could be in systems that don't have a lot of room (mini-distros or recovery disks for example). I've seen a recovery disk distro with everything you needed 2 floppies disks. Only reason I don't use floppies anymore is the ones being made are crap and don't keep data where as 14 years ago I could accidentally put mine through the wash and still access it's contents. (Cheap bastards)
Apr 28 2012
On Sunday, 29 April 2012 at 00:40:01 UTC, Era Scarecrow wrote:On Saturday, 28 April 2012 at 23:50:22 UTC, foobar wrote:floppies, are you for real?! This is only relevant if you travel a decade or so back in time. The current generation dvd/Blu-ray discs and USB sticks aren't good enough for you?On Saturday, 28 April 2012 at 21:02:25 UTC, H. S. Teoh wrote:* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I agree with the general notion here. Whatever the actual implementation details are, the API should be strongly tied to the binary in order to insure consistency and ease of use. I shouldn't need to worry if the header files match the binary library. Regarding the human readable API - that's why we have documentation for.Mmm well the main reason I see using .di files, is cases when the input library/file/dll doesn't give you much or any information. like... most dll's today. There's also tools to strip that extra debugging and structure information from your output file, so if you distribute a binary only, you still need to include it's .h file or .di file. Cases where this would be far more relevant could be in systems that don't have a lot of room (mini-distros or recovery disks for example). I've seen a recovery disk distro with everything you needed 2 floppies disks. Only reason I don't use floppies anymore is the ones being made are crap and don't keep data where as 14 years ago I could accidentally put mine through the wash and still access it's contents. (Cheap bastards)
Apr 29 2012
On Sunday, 29 April 2012 at 07:00:51 UTC, foobar wrote:floppies, are you for real?! This is only relevant if you travel a decade or so back in time. The current generation dvd/Blu-ray discs and USB sticks aren't good enough for you?What? I like my floppies... or did when they worked. Depends on what I'm doing; I mean a meg is a lot of space if your primarily doing text and using compression. But I accept it is an old technology and won't be coming back.
Apr 29 2012
On Sat, 28 Apr 2012 14:03:26 -0700, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Sat, Apr 28, 2012 at 09:58:02PM +0200, foobar wrote: [...]I have written code that will do just that. You can check it out here: https://github.com/LightBender/dmd.git. It builds both the DRuntime and Phobos perfectly, however, the Phobos makefile has not yet been updated to generate DI files. However, Phobos uses the Druntime DI files for it's build.D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse). This is nothing more than a fancy function with a delegate parameter.I disagree. Having a dedicated foreach construct allows the compiler to optimize away the delegate in certain cases. I wouldn't want to incur the cost of creating and passing a delegate in something as simple as foreach (i; 0..100), for example.* enum - enum should be completely redesigned to only implement what it's named after: enumerations.Actually, I rather like the enum idiom of declaring compile-time constants. Though it could do with a renaming to something more befitting.* version - this does not belong in a programming language. Git is a much better solution.This is an interesting idea. But using separate git branches just for having versioned code seems a bit like total overkill... plus a maintenance nightmare since you have to continue pull and merge changes to every porting branch every time development happens. Whereas having everything represented in source means that whoever writes a new feature is also responsible for making it work with whatever versions are currently out there. After-the-fact fixes are always painful.* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I proposed a while ago that .di files should be replaced by something better: omit ALL function bodies, template bodies, private members, etc., and just keep the "real" public API in the human-readable part of the file. Function and template bodies should be kept in as a binary blob readable by the compiler (which obviously needs to know them otherwise it won't be able to expand templates).(Yes the binary blob can be reverse-engineered, but so can executables, so it's a moot point. We're not trying to write cryptographic security here, but it's nice to separate what the compiler needs to know vs. what the user of a library needs to know.)-- Adam Wilson IRC: LightBender Project Coordinator The Horizon Project http://www.thehorizonproject.org/* This is a big one: get rid of *all* current compile time special syntax. It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons. This would reduce the size of the language to half of its current size, maybe even more.I have to disagree here. CTFE and compile-time features is a major reason I like D. I argue rather that compile-time features should be *improved*. The current situation is good, but not quite there yet. It can be made better. T
Apr 28 2012
On 2012-04-28 21:58, foobar wrote:D has a lot of ad-hock features which make the language needlessly large and complex. I'd strive to replace these with better general purpose mechanisms. My list: * I'd start with getting rid of foreach completely. (not just foreach_reverse). This is nothing more than a fancy function with a delegate parameter.I agree.* This is a big one: get rid of *all* current compile time special syntax. It should be replaced by a standard compilation API and the compiler should be able to use plugins/addons. This would reduce the size of the language to half of its current size, maybe even more.I agree with this one as well. At least if the compiler would be implemented like this. -- /Jacob Carlborg
Apr 29 2012
On Saturday, 28 April 2012 at 19:58:03 UTC, foobar wrote:* di files - a library should encapsulate all the info required to use it. Java Jars, .Net assemblies and even old school; Pascal units all solved this long ago.I strongly support this.
Apr 29 2012
Walter:which features in D are redundant and/or do not add significant value? ... What's your list?Finding things to remove now from D is hard, in my code I have used most D features now. And many suggestions I have seen in this thread are very bad, like removing foreach_reverse (that I use often), or "Phobos is too fat" (that is the opposite of what I'd like, I'd like D with more batteries). The features I have not used in my programs so far are: 1) Typesafe Variadic Functions for class objects (never used so far). 2) >>>= >>> (Never used so far). 3) Floating point comparison operators (never used). 4) Delimited Strings / heredoc strings (never used so far in real code, despite Perl programmers use them now and then). 5) lazy (as function argument. I have used "lazy" in some test programs, but not in real code so far). 6) Anonymous classes (used only in demo code so far). 7) Shortened floating point literals as .6 or 6. Other things that I don't like: 1) Mixed C/D array declarations (http://d.puremagic.com/issues/show_bug.cgi?id=5807 ) 2) I'd like to disallow (or fix!) default arguments of out and ref arguments (http://d.puremagic.com/issues/show_bug.cgi?id=5850 ). 3) Automatic joining of adjacent strings (a bug-prone anti-feature: ["red" "green", "blue"]). 4) Comma operator, it gives more troubles than flexibility. 5) The most complex parts of the is() syntax (to be replaced with other things). 6) Two kinds of tuples. I'd like a single tuple type in a language, but I understand this is hard to do. ------------------------- I'd also like to see some limits removed like: struct Foo {} void main() { auto f = new Foo; // currently not accepted, silly } BigInt x; switch (x) { case BigInt(0): break; default: } And I'd like some features added/improved, like: - tuple unpacking syntax; - computed gotos; - a static foreach (http://d.puremagic.com/issues/show_bug.cgi?id=4085 ); - attribute hiding error or warning (http://d.puremagic.com/issues/show_bug.cgi?id=5187 ); - safer typesafe variadics (http://d.puremagic.com/issues/show_bug.cgi?id=5212 ); - Named arguments; And few other things. Bye, bearophile
Apr 28 2012
On 4/28/2012 1:00 PM, bearophile wrote:"Phobos is too fat"As opposed to Phobos being phat?
Apr 28 2012
On Saturday, 28 April 2012 at 20:04:11 UTC, Walter Bright wrote:On 4/28/2012 1:00 PM, bearophile wrote:Well my concern is so that it doesn't end up like Python standard library, half-bitrotting and half-crap :) Huge standard library is not a good idea even for a very big language/library team, and D doesn't have one."Phobos is too fat"As opposed to Phobos being phat?
Apr 28 2012
On Sat, Apr 28, 2012 at 10:07:54PM +0200, q66 wrote:On Saturday, 28 April 2012 at 20:04:11 UTC, Walter Bright wrote:On the contrary, being able to do stuff without having to reinvent the square wheel every single time is a big plus. I used to have a strong NIH attitude -- years ago during my DOS days, I reimplemented video output routines in assembly because I wanted to use protected mode in DOS. Nothing in the C standard library worked because they are all tied to DOS or otherwise do stuff that breaks in protected mode. So I reinvented file abstractions, string processing, etc., in my own library. I was rather proud of it too: my video routines took advantage of features of my particular chosen video mode, so I could use the i386's built-in loop instructions and other such things to output characters really fast. In retrospect, it was a fun and very educational experience. But to be frank, you can only reinvent the C standard library so many times before you get totally sick and tired of it. I mean, I've implemented linked lists, hand-made lexers, parsers, etc., who knows how many times, and nowadays the thought of having to do it all over again just makes me feel, "I should be doing better things with my time". The whole point of a standard library is that if somebody has written that code before, and it's general enough for everyday use, then you shouldn't need to download this, install that, configure the other, before you can use it. It's a major plus if you're publishing code to be able to say, just download my sources and compile it with the language standard library and it will all work. As opposed to, if you want to compile my code, you need library X and Y which depend on W and Z, all of which have to be downloaded from different places all over the 'net and you better make sure you get the right versions otherwise everything will break. Besides, the whole point of a library is that only what you need is actually linked in. You don't walk around carrying every book from your bookshelf just because you *might* need to refer to one of them on some rare occasion. But the library itself doesn't need to be minimal, in fact, rather to the contrary. (That's why it's called a "library".) T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- SchoolboyOn 4/28/2012 1:00 PM, bearophile wrote:Well my concern is so that it doesn't end up like Python standard library, half-bitrotting and half-crap :) Huge standard library is not a good idea even for a very big language/library team, and D doesn't have one."Phobos is too fat"As opposed to Phobos being phat?
Apr 28 2012
On Saturday, 28 April 2012 at 21:19:00 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 10:07:54PM +0200, q66 wrote:Well I'm not obviously saying the features should disappear, what I had in mind was some kind of distribution system for small packages, kinda like luaforge or CPAN, where everyone could find what they need for their project. But keep Phobos itself small.On Saturday, 28 April 2012 at 20:04:11 UTC, Walter Bright wrote:On the contrary, being able to do stuff without having to reinvent the square wheel every single time is a big plus. I used to have a strong NIH attitude -- years ago during my DOS days, I reimplemented video output routines in assembly because I wanted to use protected mode in DOS. Nothing in the C standard library worked because they are all tied to DOS or otherwise do stuff that breaks in protected mode. So I reinvented file abstractions, string processing, etc., in my own library. I was rather proud of it too: my video routines took advantage of features of my particular chosen video mode, so I could use the i386's built-in loop instructions and other such things to output characters really fast. In retrospect, it was a fun and very educational experience. But to be frank, you can only reinvent the C standard library so many times before you get totally sick and tired of it. I mean, I've implemented linked lists, hand-made lexers, parsers, etc., who knows how many times, and nowadays the thought of having to do it all over again just makes me feel, "I should be doing better things with my time". The whole point of a standard library is that if somebody has written that code before, and it's general enough for everyday use, then you shouldn't need to download this, install that, configure the other, before you can use it. It's a major plus if you're publishing code to be able to say, just download my sources and compile it with the language standard library and it will all work. As opposed to, if you want to compile my code, you need library X and Y which depend on W and Z, all of which have to be downloaded from different places all over the 'net and you better make sure you get the right versions otherwise everything will break. Besides, the whole point of a library is that only what you need is actually linked in. You don't walk around carrying every book from your bookshelf just because you *might* need to refer to one of them on some rare occasion. But the library itself doesn't need to be minimal, in fact, rather to the contrary. (That's why it's called a "library".) TOn 4/28/2012 1:00 PM, bearophile wrote:Well my concern is so that it doesn't end up like Python standard library, half-bitrotting and half-crap :) Huge standard library is not a good idea even for a very big language/library team, and D doesn't have one."Phobos is too fat"As opposed to Phobos being phat?
Apr 28 2012
On Sat, Apr 28, 2012 at 11:21:52PM +0200, q66 wrote: [...]Well I'm not obviously saying the features should disappear, what I had in mind was some kind of distribution system for small packages, kinda like luaforge or CPAN, where everyone could find what they need for their project. But keep Phobos itself small.If you're talking about very specific, niche features (like parsing protein structure data files), then I agree they should be distributed in separate libraries. But generic stuff that can be used in a wide array of tasks should go in the standard library. Again I say, being able to distribute your sources without requiring the user to download 50 different libraries just to compile it, is a big plus to me. Being able to say "just compile with the standard library" is best, because it means people can just download my code and compile it immediately. Same goes for binary distribution: it's much much better to say "here, just download this binary and run it with the language standard library" than to say "download this binary, then library X, then library Y, then library Z which is needed by library X, then library W needed by ...". T -- Freedom of speech: the whole world has no right *not* to hear my spouting off!
Apr 28 2012
On Saturday, 28 April 2012 at 21:19:00 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 10:07:54PM +0200, q66 wrote:OMG I love you :) A long time ago when I began programming I came to a distinct conclusion that anything I write has to be able to compile and just work with only the standard library. I don't want to make people go out of their way to get this or that. * If you have something that requires multimedia, then fine a library will help. * If you have to have something that does translations between other languages and makes sense, then use it. But for everything that's just basic work processing and otherwise, there is no reason you should have an external library used. Need compression? If the standard library (like C) doesn't include something, then what do you choose? LZMA? lzop? gzip/zlib? bzip2? Depends on how heavy duty you need. If a basic compression is included then you will use it unless you REALLY need the extra speed or compression ratio. "Make everything as simple as possible, but no simpler." -- Albert EinsteinOn Saturday, 28 April 2012 at 20:04:11 UTC, Walter BrightThe whole point of a standard library is that if somebody has written that code before, and it's general enough for everyday use, then you shouldn't need to download this, install that, configure the other, before you can use it. It's a major plus if you're publishing code to be able to say, just download my sources and compile it with the language standard library and it will all work. As opposed to, if you want to compile my code, you need library X and Y which depend on W and Z, all of which have to be downloaded from different places all over the 'net and you better make sure you get the right versions otherwise everything will break.
Apr 28 2012
On Saturday, April 28, 2012 22:00:52 bearophile wrote:2) I'd like to disallow (or fix!) default arguments of out and ref arguments (http://d.puremagic.com/issues/show_bug.cgi?id=5850 ).If the changes to ref and const ref that were discussed during the beta are fully fleshed out and implemented, then it'll be perfectly legal to pass a temporary value to a ref in many cases (if not in general), in which case having them take a default argument wouldn't be a problem at all. But as long as ref can't take temporaries, having it take a default argument makes no sense at all.3) Automatic joining of adjacent strings (a bug-prone anti-feature: ["red" "green", "blue"]).Agreed. - Jonathan M Davis
Apr 28 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value?A more general answer. From my experience the real problem with language features is not their high number, because I am able to learn hundreds of them well. The main problem comes from bad/broken interaction between features, hard to see side effects of features, and so on. Bye, bearophile
Apr 28 2012
forum.dlang.org apparently failed to post this 10 minutes ago, retrying. On Tuesday, 10 July 2012 at 02:43:05 UTC, Era Scarecrow wrote:On Tuesday, 10 July 2012 at 01:41:29 UTC, bearophile wrote:...David Piepgrass:This use case is pretty complex, so if I port this to D, I'd probably just cast away const/immutable where necessary.You are not the first person that says similar things. So D docs need to stress more than casting away const/immutable in D is rather more dangerous than doing the same thing in C++.Let's say a class/struct is a book with Page protectors signifying 'const(ant)'. You promise to return the book to the library without making any changes; Although you promised you wouldn't make changes, you still take the Page protectors off and make make notes on the outer edges or make adjustments in the text, then return the book. Is this wise? This isn't C++. If something shouldn't change, then don't change it god damn it. If it needs to change it isn't const(ant) and shouldn't suggest it is.The difficulty, in case you missed it, is that somebody else (the Object class) says that certain functions are const, but in certain cases we really, really want to mutate something, either for efficiency or because "that's just how the data structure works". If a data structure needs to mutate itself when read, yeah, maybe its functions should not be marked const, but quite often the "const" is inherited from Object or some interface that (quite reasonably, it would seem) expects functions that /read stuff/ to be const. And yet we can't drop const from Object or such interfaces, because there is other code elsewhere that /needs/ const to be there. So far I have no solution to the dilemma in mind, btw. But the idea someone had of providing two (otherwise identical) functions, one const and one non-const, feels like a kludge to me, and note that anybody with an object would expect to be able to call the const version on any Object.Seriously, it's not that hard a concept. I guess if something doesn't port well from C++ then redesign it. Some things done in C++ are hacks due to the language's limitations and faults.My particular data structure (a complex beast) contains a mutable tree of arbitrary size, which the user can convert to a conceptually immutable tree in O(1) time by calling Clone(). This marks a flag in the root node that says "read-only! do not change" and shares the root between the clones. At this point it should be safe to cast the clone to immutable. However, the original, mutable-typed version still exists. As the user requests changes to the mutable copy in the future, parts of the tree are duplicated to avoid changing the immutable nodes, with one exception: the read-only flag in various parts of the original, immutable tree will gradually be set to true. In this case, I don't think the D type system could do anything to help ensure that I don't modify the original tree that is supposed to be immutable. Since the static type of internal references must either be all mutable or all immutable, they will be typed mutable in the mutable copy, and immutable in the immutable copy, even though the two copies are sharing the same memory. And one flag, the read-only flag, must be mutable in this data structure, at least the transition from false->true must happen *after* the immutable copy is created; otherwise, Clone() would have to run in O(N) time, to mark every node read-only. This fact, however, does not affect the immutable copy in any way.
Jul 10 2012
On 04/28/2012 08:47 PM, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- Associative array literals as non-associative array initializers [1] - C style array declarations [2] - 'align' declaration [3] - 'synchronized' [4] - special treatment of built-in types during parsing [5] - the arcane restrictions on which exact kind of argument can be used to substitute which kind of template parameter I think all other language features are useful and except for new instance.Class and 'this' template parameters, I think they all occur in my code. (But those would certainly come in handy for a somewhat more OO-like style of programming.) (There are a few features that I'd like to give a (mostly syntactic) overhaul, but that is not what is discussed here.) Explanations: [1] Actually I think the functionality is very useful, but the syntax is probably confusing for many fellow D programmers. CTFE should enable a library implementation. [2] They violate the 'same syntax, same behaviour' rule, and they don't add a lot of value. [3] I have not understood until now what exactly the guarantees are that it gives, so take this with a grain of salt. I know that it is not useful as implemented DMD for typical alignment tasks, and that GDC implements different semantics. Can you explain to me what it is useful for? [4] It adds memory overhead for the monitor to every single class, even though most classes are explicitly _typed_ as unshared. [5] It is for example impossible to directly string mixin "int".
Apr 28 2012
On 04/28/2012 10:24 PM, Timon Gehr wrote:On 04/28/2012 08:47 PM, Walter Bright wrote:Oh, completely forgot about that one: - 'in' operator returning a pointer to the element.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- Associative array literals as non-associative array initializers [1] - C style array declarations [2] - 'align' declaration [3] - 'synchronized' [4] - special treatment of built-in types during parsing [5] - the arcane restrictions on which exact kind of argument can be used to substitute which kind of template parameter
Apr 28 2012
On Sun, Apr 29, 2012 at 12:39:03AM +0200, Timon Gehr wrote:On 04/28/2012 10:24 PM, Timon Gehr wrote:Yeah that one elicited a WAT from me when I first started using it. Surprisingly enough, it sounded OK when I read it in TDPL, but when I started using it I realized just how b0rken it is. T -- People tell me that I'm paranoid, but they're just out to get me.On 04/28/2012 08:47 PM, Walter Bright wrote:Oh, completely forgot about that one: - 'in' operator returning a pointer to the element.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- Associative array literals as non-associative array initializers [1] - C style array declarations [2] - 'align' declaration [3] - 'synchronized' [4] - special treatment of built-in types during parsing [5] - the arcane restrictions on which exact kind of argument can be used to substitute which kind of template parameter
Apr 28 2012
On 29-04-2012 00:49, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 12:39:03AM +0200, Timon Gehr wrote:How so? It's seemed entirely reasonable to me. -- - AlexOn 04/28/2012 10:24 PM, Timon Gehr wrote:Yeah that one elicited a WAT from me when I first started using it. Surprisingly enough, it sounded OK when I read it in TDPL, but when I started using it I realized just how b0rken it is. TOn 04/28/2012 08:47 PM, Walter Bright wrote:Oh, completely forgot about that one: - 'in' operator returning a pointer to the element.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- Associative array literals as non-associative array initializers [1] - C style array declarations [2] - 'align' declaration [3] - 'synchronized' [4] - special treatment of built-in types during parsing [5] - the arcane restrictions on which exact kind of argument can be used to substitute which kind of template parameter
Apr 29 2012
On Sun, Apr 29, 2012 at 10:21:19PM +0200, Alex Rønne Petersen wrote:On 29-04-2012 00:49, H. S. Teoh wrote:[...]On Sun, Apr 29, 2012 at 12:39:03AM +0200, Timon Gehr wrote:[...]- 'in' operator returning a pointer to the element.Yeah that one elicited a WAT from me when I first started using it. Surprisingly enough, it sounded OK when I read it in TDPL, but when I started using it I realized just how b0rken it is.How so? It's seemed entirely reasonable to me.[...] I was expecting it to return bool. It also precludes bool-valued AA's from being implemented using bit arrays, since you can't return a pointer to a bit. T -- In order to understand recursion you must first understand recursion.
Apr 29 2012
On Sunday, April 29, 2012 00:39:03 Timon Gehr wrote:Oh, completely forgot about that one: - 'in' operator returning a pointer to the element.Really? I use that all the time with AAs. Without that, you would have to do two lookups to get an object which might not be in the container, so it would be less efficient. I'd hate it if in stopped returning a pointer. We'd just have to add some other function which does the exact same thing as in now, and then I'd use in a _lot_ less. - Jonathan M Davis
Apr 28 2012
Jonathan M Davis:LDC1 compiler introduced a small optimization, it looks for nearby associative array lookups and removes the second of them where possible. In my code I have seen this frees me to use "in" nearby followed by [], with the same efficiency of a single AA lookup. With this small optimization, D "in" is free to return a more clean boolean. This optimization doesn't work if you want to store the pointer returned by "in" to use it later, but in my code this pattern doesn't happen, I think it's quite uncommon. Java/JavaScript/Lua show that the language design has to focus on what's hard to optimize away for the compiler, like offering ways to the programmer to specify higher level semantics (like asserting: foo(a,b) is equal to foo(b,a)), instead of focusing on what a not dumb static compiler (not even a JIT) is able to optimize away. Bye, bearophile- 'in' operator returning a pointer to the element.Really? I use that all the time with AAs. Without that, you would have to do two lookups to get an object which might not be in the container, so it would be less efficient.
Apr 28 2012
On Sunday, April 29, 2012 01:42:05 bearophile wrote:Jonathan M Davis:I really don't see anything "unclean" about returing a pointer. It does the job fantastically, and you can use it in conditional expressions just like you would use a bool. Also, while it may work for the most part, I'd be very skeptical about the compiler being able to optimize out lookups as well as simply using in would - especially in cases where you don't immediately use the pointer.LDC1 compiler introduced a small optimization, it looks for nearby associative array lookups and removes the second of them where possible. In my code I have seen this frees me to use "in" nearby followed by [], with the same efficiency of a single AA lookup. With this small optimization, D "in" is free to return a more clean boolean.- 'in' operator returning a pointer to the element.Really? I use that all the time with AAs. Without that, you would have to do two lookups to get an object which might not be in the container, so it would be less efficient.This optimization doesn't work if you want to store the pointer returned by "in" to use it later, but in my code this pattern doesn't happen, I think it's quite uncommon.Storing it for later use within the function is quite common. Storing it in a member variable or the like should be _very_ uncommon, since it's almost always a bad idea. But even just storing it in a local variable to use later could destroy the locality enough to defeat LDC's optimization. - Jonathan M Davis
Apr 28 2012
On Saturday, 28 April 2012 at 23:51:43 UTC, Jonathan M Davis wrote:But even just storing it in a local variable to use later could destroy the locality enough to defeat LDC's optimization.Huh? I can't think of a situation where a hash table lookup would entail less indirections than dereferencing a pointer stored in a register (resp. the stack, depending on scheduling). David
Apr 29 2012
On Sunday, April 29, 2012 10:07:38 David Nadlinger wrote:On Saturday, 28 April 2012 at 23:51:43 UTC, Jonathan M Davis wrote:If you have something like if(key in aa) { // lots of code func(aa[key]); } the compiler is not necessarily going to be able to determine that the AA has not been changed such that aa[key] can use the same lookup that key in aa did rather than redoing the lookup. A prime example would be if(key in aa) { foo(aa); func(aa[key]); } The compiler doesn't necessarily know that foo won't remove key from aa, so it can't save the result of key in aa to reuse rather than calling aa[key], whereas the programmer could know that foo doesn't do anything to aa which would make a pointer to the element invalid and can guarantee that only one lookup occurs by doing if(auto value = key in aa) { foo(aa); func(value); } And that's just one case where the compiler can't make such an optimization but the programmer can. It's _far_ better iMHO to have in return a pointer than to rely on the compiler removing extraneous lookups. - Jonathan M DavisBut even just storing it in a local variable to use later could destroy the locality enough to defeat LDC's optimization.Huh? I can't think of a situation where a hash table lookup would entail less indirections than dereferencing a pointer stored in a register (resp. the stack, depending on scheduling).
Apr 29 2012
On Sunday, 29 April 2012 at 08:20:59 UTC, Jonathan M Davis wrote:The compiler doesn't necessarily know that foo won't remove key from aa, so it can't save the result of key in aa to reuse rather than calling aa[key], whereas the programmer could know that foo doesn't do anything to aa which would make a pointer to the element invalid and can guarantee that only one lookup occurs by doing […]Yes, point taken, but what does this have to do with locality? David
Apr 29 2012
On Sunday, April 29, 2012 10:22:44 David Nadlinger wrote:On Sunday, 29 April 2012 at 08:20:59 UTC, Jonathan M Davis wrote:I think that you're thinking of something completely different about th= e term=20 locality than I meant. I meant locality in terms of how close the aa[ke= y]=20 expression was to the key in aa expression within the function - i.e. h= ow=20 local they were to each other. I may have misused the term though. I do= n't=20 know. - Jonathan M DavisThe compiler doesn't necessarily know that foo won't remove key from aa, so it can't save the result of key in aa to reuse rather than calling aa[key], whereas the programmer could know that foo doesn't do anything to aa which would make a pointer to the element invalid and can guarantee that only one lookup occurs by doing [=E2=80=A6]=20 Yes, point taken, but what does this have to do with locality?
Apr 29 2012
On Sunday, 29 April 2012 at 08:30:15 UTC, Jonathan M Davis wrote:On Sunday, April 29, 2012 10:22:44 David Nadlinger wrote:Okay, then it was just a misunderstanding, I thought about memory locality. DavidYes, point taken, but what does this have to do with locality?I think that you're thinking of something completely different about the term locality than I meant. I meant locality in terms of how close the aa[key] expression was to the key in aa expression within the function - i.e. how local they were to each other. I may have misused the term though. I don't know.
Apr 29 2012
On 04/29/2012 10:20 AM, Jonathan M Davis wrote:On Sunday, April 29, 2012 10:07:38 David Nadlinger wrote:Well, what if the programmer "knows" that foo does not change 'aa', but it actually does? Then there would possibly be a segmentation fault. This implies that the 'in' operator cannot be used in safe code. (Or there would have to be a special case, that allows 'in' if the result is directly cast to bool.)On Saturday, 28 April 2012 at 23:51:43 UTC, Jonathan M Davis wrote:If you have something like if(key in aa) { // lots of code func(aa[key]); } the compiler is not necessarily going to be able to determine that the AA has not been changed such that aa[key] can use the same lookup that key in aa did rather than redoing the lookup. A prime example would be if(key in aa) { foo(aa); func(aa[key]); } The compiler doesn't necessarily know that foo won't remove key from aa, so it can't save the result of key in aa to reuse rather than calling aa[key], whereas the programmer could know that foo doesn't do anything to aa which would make a pointer to the element invalid and can guarantee that only one lookup occurs by doing if(auto value = key in aa) { foo(aa); func(value); } And that's just one case where the compiler can't make such an optimization but the programmer can. It's _far_ better iMHO to have in return a pointer than to rely on the compiler removing extraneous lookups. - Jonathan M DavisBut even just storing it in a local variable to use later could destroy the locality enough to defeat LDC's optimization.Huh? I can't think of a situation where a hash table lookup would entail less indirections than dereferencing a pointer stored in a register (resp. the stack, depending on scheduling).
Apr 29 2012
On Sunday, April 29, 2012 10:37:10 Timon Gehr wrote:Well, what if the programmer "knows" that foo does not change 'aa', but it actually does? Then there would possibly be a segmentation fault. This implies that the 'in' operator cannot be used in safe code. (Or there would have to be a special case, that allows 'in' if the result is directly cast to bool.)It's exactly as safe as any iterator or range which could be invalidated - both of which can occur in safe code. Any of those could blow up in entertaining ways if you use them after they've been invalidated. Pointers are considered safe. It's pointer arithmetic which isn't. - Jonathan M Davis
Apr 29 2012
On Sun, Apr 29, 2012 at 01:46:25AM -0700, Jonathan M Davis wrote:On Sunday, April 29, 2012 10:37:10 Timon Gehr wrote:[...] I get that this discussion is about what type 'in' should return, but taking a step back, isn't it all moot because you could just use the .get() method? T -- Let's not fight disease by killing the patient. -- Sean 'Shaleh' PerryWell, what if the programmer "knows" that foo does not change 'aa', but it actually does? Then there would possibly be a segmentation fault. This implies that the 'in' operator cannot be used in safe code. (Or there would have to be a special case, that allows 'in' if the result is directly cast to bool.)It's exactly as safe as any iterator or range which could be invalidated - both of which can occur in safe code. Any of those could blow up in entertaining ways if you use them after they've been invalidated. Pointers are considered safe. It's pointer arithmetic which isn't.
Apr 29 2012
On 04/30/2012 04:21 AM, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 01:46:25AM -0700, Jonathan M Davis wrote:The AA might actually contain the provided default value, so 'get' is not always a good match.On Sunday, April 29, 2012 10:37:10 Timon Gehr wrote:[...] I get that this discussion is about what type 'in' should return, but taking a step back, isn't it all moot because you could just use the .get() method? TWell, what if the programmer "knows" that foo does not change 'aa', but it actually does? Then there would possibly be a segmentation fault. This implies that the 'in' operator cannot be used in safe code. (Or there would have to be a special case, that allows 'in' if the result is directly cast to bool.)It's exactly as safe as any iterator or range which could be invalidated - both of which can occur in safe code. Any of those could blow up in entertaining ways if you use them after they've been invalidated. Pointers are considered safe. It's pointer arithmetic which isn't.
Apr 30 2012
On 4/29/12, Timon Gehr <timon.gehr gmx.ch> wrote:- 'in' operator returning a pointer to the element.AFAIK this is a property of how the opIn_r function is implemented, nothing much to do with the language itself. But it does allow for some neat tricks, like: int[int] hash; hash[1] = 2; int value = *enforce(1 in hash, new Exception("1 not in hash")); assert(value == 2); or: if (auto val = 1 in hash) ...use val pointer (+ if it's a class/struct pointer you still have access to the dot syntax) else ... errors..
Apr 28 2012
On 04/29/2012 06:36 AM, Andrej Mitrovic wrote:On 4/29/12, Timon Gehr<timon.gehr gmx.ch> wrote:Well, AAs are part of the language.- 'in' operator returning a pointer to the element.AFAIK this is a property of how the opIn_r function is implemented, nothing much to do with the language itself.But it does allow for some neat tricks, like: int[int] hash; hash[1] = 2; int value = *enforce(1 in hash, new Exception("1 not in hash")); assert(value == 2); or: if (auto val = 1 in hash) ...use val pointer (+ if it's a class/struct pointer you still have access to the dot syntax) else ... errors..I know, but 'in' is somewhat of a misnomer. Anyway, it is not a huge issue.
Apr 29 2012
On 29-04-2012 06:36, Andrej Mitrovic wrote:On 4/29/12, Timon Gehr<timon.gehr gmx.ch> wrote:I hate to nitpick and all that, but opBinaryRight!"in" actually works now. ;)- 'in' operator returning a pointer to the element.AFAIK this is a property of how the opIn_r function is implemented, nothing much to do with the language itself.But it does allow for some neat tricks, like: int[int] hash; hash[1] = 2; int value = *enforce(1 in hash, new Exception("1 not in hash")); assert(value == 2); or: if (auto val = 1 in hash) ...use val pointer (+ if it's a class/struct pointer you still have access to the dot syntax) else ... errors..-- - Alex
Apr 29 2012
On 4/29/12, Alex R=F8nne Petersen <xtzgzorex gmail.com> wrote:I hate to nitpick and all that, but opBinaryRight!"in" actually works now. ;)Yes and then you get to have those nice template instantiation errors, which make no sense at all: struct Foo { auto opIn_r(string op)(int i) { return 1; } } struct Bar { auto opBinaryRight(string op)(int i) { return 1; } } void main() { Foo foo; auto x =3D "" in foo; Bar bar; auto y =3D "" in bar; } Foo: test.d(34): Error: template test.Foo.opIn_r does not match any function template declaration test.d(16): Error: template test.Foo.opIn_r(string op) cannot deduce template function from argument types !()(string) Bar: test.d(37): Error: rvalue of in expression must be an associative array, no= t Bar The Bar error message is completely useless.
Apr 29 2012
On 4/29/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:struct Foo { auto opIn_r(string op)(int i) { return 1; } }Sorry that's wrong, should be: struct Foo { auto opIn_r(int i) { return 1; } } And then you get: test.d(25): Error: function test.Foo.opIn_r (int i) is not callable using argument types (string) test.d(25): Error: cannot implicitly convert expression ("") of type string to int which much better than Bar's error message.
Apr 29 2012
On 29-04-2012 22:52, Andrej Mitrovic wrote:On 4/29/12, Andrej Mitrovic<andrej.mitrovich gmail.com> wrote:I think all of the error messages you posted could need improvement. In any case, that's a compiler issue if anything. -- - Alexstruct Foo { auto opIn_r(string op)(int i) { return 1; } }Sorry that's wrong, should be: struct Foo { auto opIn_r(int i) { return 1; } } And then you get: test.d(25): Error: function test.Foo.opIn_r (int i) is not callable using argument types (string) test.d(25): Error: cannot implicitly convert expression ("") of type string to int which much better than Bar's error message.
Apr 29 2012
On Sat, Apr 28, 2012 at 11:47:31AM -0700, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types.D has typedef?? Wow. And I thought I had a good grasp of D.What's your list?Comma operator. foreach_reverse. with statements. They make code hard to read, and besides you can (or should be able to) alias long expressions into a short identifier for this purpose anyway. The great variety of string quoting syntax, while useful, seem to need some cleanup and unification. Get rid of r"", `` works just fine. (Or vice versa, but not both.) Delimited strings and token strings may be possible to be unified, perhaps? It's about time octal literals went the way of the bit bucket. There's probably more, I'll post them as I think of them. T -- Questions are the beginning of intelligence, but the fear of God is the beginning of wisdom.
Apr 28 2012
On 28-04-2012 22:43, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 11:47:31AM -0700, Walter Bright wrote:It "has" typedef, but it is deprecated.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types.D has typedef?? Wow. And I thought I had a good grasp of D.+1.What's your list?Comma operator.foreach_reverse.+1.with statements. They make code hard to read, and besides you can (or should be able to) alias long expressions into a short identifier for this purpose anyway.I don't think I agree entirely here. If you have very long sequences of statements operating on the same object, with can be very useful. That said, I recognize that the current implementation of with needs some work.The great variety of string quoting syntax, while useful, seem to need some cleanup and unification. Get rid of r"", `` works just fine. (Or vice versa, but not both.) Delimited strings and token strings may be possible to be unified, perhaps?IMHO r"" is better than `` for the simple reason that typing `` is extremely annoying on non-US keyboards.It's about time octal literals went the way of the bit bucket.I think those are already deprecated.There's probably more, I'll post them as I think of them. T-- - Alex
Apr 29 2012
On Sun, Apr 29, 2012 at 10:26:40PM +0200, Alex Rønne Petersen wrote:On 28-04-2012 22:43, H. S. Teoh wrote:[...][...] I think the correct solution here is to use alias. (If that doesn't work, then it should be made to work. It's a lot cleaner and doesn't introduce potentially nasty ambiguities into code, as well as make code more readable without needing to implement nested symbol tables in your brain.) T -- Help a man when he is in trouble and he will remember you when he is in trouble again.with statements. They make code hard to read, and besides you can (or should be able to) alias long expressions into a short identifier for this purpose anyway.I don't think I agree entirely here. If you have very long sequences of statements operating on the same object, with can be very useful. That said, I recognize that the current implementation of with needs some work.
Apr 29 2012
H. S. Teoh:I think the correct solution here is to use alias. (If that doesn't work, then it should be made to work. It's a lot cleaner and doesn't introduce potentially nasty ambiguities into code,What ambiguities? Bye, bearophile
Apr 30 2012
On Mon, Apr 30, 2012 at 10:21:23AM +0200, bearophile wrote:H. S. Teoh:[...] When you have nested with's. Or when the object members shadow local variables in the parent scope. struct S { int x; } void main() { int x, y; S s; with(s) { x = 1; y = 2; } } Technically it's unambiguous which symbols are being referred to, but it makes the code hard to read because casual scanning will usually get it wrong. Plus, you're entirely at the mercy of the definition of S. If it's an imported object from an external library, for example, then when upstream makes changes to their struct/class there's a risk of introducing subtle errors into existing, correct code (by suddenly interpreting an identifier differently). This is never good. It gets worse with nested with's: when any object being with'd changes, you risk identifier collision. The worst thing is that this can happen just by upstream(s) changing object definitions, with no change in user code. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".I think the correct solution here is to use alias. (If that doesn't work, then it should be made to work. It's a lot cleaner and doesn't introduce potentially nasty ambiguities into code,What ambiguities?
Apr 30 2012
On Mon, 30 Apr 2012 17:35:14 +0200, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Mon, Apr 30, 2012 at 10:21:23AM +0200, bearophile wrote:I think struct literals is worse in this regard: struct S { int a; int b; } user code: S(1, 2); The author of S cleans up the struct and changes the order: struct S { int b; int a; } Suddely user code has bugs. I believe the reason named parameters hasn't been introduced is because the names becomes part of the public interface. Well.. With struct literals, the _position_ of the parameters is part of the interface.H. S. Teoh:[...] When you have nested with's. Or when the object members shadow local variables in the parent scope. struct S { int x; } void main() { int x, y; S s; with(s) { x = 1; y = 2; } } Technically it's unambiguous which symbols are being referred to, but it makes the code hard to read because casual scanning will usually get it wrong. Plus, you're entirely at the mercy of the definition of S. If it's an imported object from an external library, for example, then when upstream makes changes to their struct/class there's a risk of introducing subtle errors into existing, correct code (by suddenly interpreting an identifier differently). This is never good. It gets worse with nested with's: when any object being with'd changes, you risk identifier collision. The worst thing is that this can happen just by upstream(s) changing object definitions, with no change in user code. TI think the correct solution here is to use alias. (If that doesn't work, then it should be made to work. It's a lot cleaner and doesn't introduce potentially nasty ambiguities into code,What ambiguities?
Apr 30 2012
On Monday, 30 April 2012 at 15:38:41 UTC, simendsjo wrote:I think struct literals is worse in this regard: struct S { int a; int b; } user code: S(1, 2); The author of S cleans up the struct and changes the order: struct S { int b; int a; } Suddely user code has bugs. I believe the reason named parameters hasn't been introduced is because the names becomes part of the public interface. Well.. With struct literals, the _position_ of the parameters is part of the interface.Structs provide POD value types and as such MUST include the position as part of the interface. The memory layout of these types is used to copy, compare, transmit over the net, etc. If you want encapsulation you need to at the least to define a ctor or maybe change to a class. I'd be very upset if I defined a struct for serialization/transmitting over the net/etc and changing its memory _didn't_ cause loud compiler errors. named parameters are 99% of the time a horrible idea and likely indicate a design flaw.
Apr 30 2012
foobar:named parameters are 99% of the time a horrible idea and likely indicate a design flaw.Named arguments help avoid some bugs, make the code more readable, and having used them for many years, they don't seem to indicate significant flaws in my code. Bye, bearophile
Apr 30 2012
H. S. Teoh:When you have nested with's. Or when the object members shadow local variables in the parent scope. struct S { int x; } void main() { int x, y; S s; with(s) { x = 1; y = 2; } }That code doesn't compile: test.d(10): Error: with symbol test.S.x is shadowing local symbol test.main.x Bye, bearophile
Apr 30 2012
On Mon, Apr 30, 2012 at 05:47:59PM +0200, bearophile wrote:H. S. Teoh:[...] Which means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily broken (if you had just used aliases instead, there would be no problem). T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. ChestertonWhen you have nested with's. Or when the object members shadow local variables in the parent scope. struct S { int x; } void main() { int x, y; S s; with(s) { x = 1; y = 2; } }That code doesn't compile: test.d(10): Error: with symbol test.S.x is shadowing local symbol test.main.x
Apr 30 2012
H. S. Teoh:Which means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily brokenHow? (I think you are wrong again). Bye, bearohile
Apr 30 2012
On Mon, Apr 30, 2012 at 06:54:31PM +0200, bearophile wrote:H. S. Teoh:[...] struct S { int x; } void main() { int y; S s; with(s) { x = 1; y = 2; } } This works. Now suppose S is updated to: struct S { int x; int y; } Now the program fails to compile because S.y conflicts with the local y. This is bad because unrelated code is broken just by changing S: it breaks encapsulation. This is just a small example; imagine if a lot of code uses S. Many places may break when S changes just because they happen to use the wrong local variable names. Whereas if you had _not_ used with, this is a non-problem, since you'd be referring to s.x, and the fact that S now has a new member does not break any existing code regardless of how it was named. T -- People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANGWhich means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily brokenHow? (I think you are wrong again).
Apr 30 2012
H. S. Teoh:This is bad because unrelated code is broken just by changing S: it breaks encapsulation. This is just a small example; imagine if a lot of code uses S. Many places may break when S changes just because they happen to use the wrong local variable names.But it's a kind of safe breaking, it doesn't cause a lot of silent bugs. I have found with useful in many situation to reduce the noise in my code. Bye, bearophile
Apr 30 2012
On 30-04-2012 19:05, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 06:54:31PM +0200, bearophile wrote:You always risk breaking *something* when you change an interface, whether it's through adding or removing members. The problem you point out is not at all specific to with. Consider UFCS: You have struct S and free function foo operating on S. Upstream now adds a method foo to S. -- - AlexH. S. Teoh:[...] struct S { int x; } void main() { int y; S s; with(s) { x = 1; y = 2; } } This works. Now suppose S is updated to: struct S { int x; int y; } Now the program fails to compile because S.y conflicts with the local y. This is bad because unrelated code is broken just by changing S: it breaks encapsulation. This is just a small example; imagine if a lot of code uses S. Many places may break when S changes just because they happen to use the wrong local variable names. Whereas if you had _not_ used with, this is a non-problem, since you'd be referring to s.x, and the fact that S now has a new member does not break any existing code regardless of how it was named. TWhich means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily brokenHow? (I think you are wrong again).
Apr 30 2012
On 04/30/2012 07:05 PM, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 06:54:31PM +0200, bearophile wrote:It is not unrelated.H. S. Teoh:[...] struct S { int x; } void main() { int y; S s; with(s) { x = 1; y = 2; } } This works. Now suppose S is updated to: struct S { int x; int y; } Now the program fails to compile because S.y conflicts with the local y. This is bad because unrelated codeWhich means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily brokenHow? (I think you are wrong again).is broken just by changing S: it breaks encapsulation.No it does not. Changing an interface is bound to break code.This is just a small example; imagine if a lot of code uses S. Many places may break when S changes just because they happen to use the wrong local variable names.That is an extremely constructed argument. I cannot imagine that this will ever be a problem in practice.Whereas if you had _not_ used with, this is a non-problem, since you'd be referring to s.x, and the fact that S now has a new member does not break any existing code regardless of how it was named.int* x = cast(int*)&s; int y = *x; S t = *cast(S*)&y; static if(!is(typeof(S.y)){ ... }
Apr 30 2012
On 04/30/2012 05:35 PM, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 10:21:23AM +0200, bearophile wrote:You probably should try compiling that code. ;)H. S. Teoh:[...] When you have nested with's. Or when the object members shadow local variables in the parent scope. struct S { int x; } void main() { int x, y; S s; with(s) { x = 1; y = 2; } } [snip.]I think the correct solution here is to use alias. (If that doesn't work, then it should be made to work. It's a lot cleaner and doesn't introduce potentially nasty ambiguities into code,What ambiguities?
Apr 30 2012
On 4/30/12, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:I think the correct solution here is to use alias. (If that doesn't work, then it should be made to work..)It probably will. Quote Andrei: "Yah, we should add that at some point. Walter and I discussed about it and it's virtually approved. But to be on the conservative side, it's not for expressions but for mere pointer-chasing chains." So this would probably work: alias var.some.deeply.nested.object obj; // use obj here.. I think that's what is being discussed w.r.t. with()?
Apr 29 2012
On 2012-04-29 22:26, Alex Rønne Petersen wrote:IMHO r"" is better than `` for the simple reason that typing `` is extremely annoying on non-US keyboards.`` is better because you don't have to escape ". -- /Jacob Carlborg
Apr 30 2012
On 30-04-2012 09:08, Jacob Carlborg wrote:On 2012-04-29 22:26, Alex Rønne Petersen wrote:That only applies when you actually have " in the string. I think both have their uses. -- - AlexIMHO r"" is better than `` for the simple reason that typing `` is extremely annoying on non-US keyboards.`` is better because you don't have to escape ".
Apr 30 2012
On 2012-04-30 17:14, Alex Rønne Petersen wrote:On 30-04-2012 09:08, Jacob Carlborg wrote:When is r"" a better use than ``? We already have the regular "". -- /Jacob CarlborgOn 2012-04-29 22:26, Alex Rønne Petersen wrote:That only applies when you actually have " in the string. I think both have their uses.IMHO r"" is better than `` for the simple reason that typing `` is extremely annoying on non-US keyboards.`` is better because you don't have to escape ".
Apr 30 2012
On 30-04-2012 21:42, Jacob Carlborg wrote:On 2012-04-30 17:14, Alex Rønne Petersen wrote:You don't have escape sequences inside r"", so they can be useful if you have backslashes in your string. -- - AlexOn 30-04-2012 09:08, Jacob Carlborg wrote:When is r"" a better use than ``? We already have the regular "".On 2012-04-29 22:26, Alex Rønne Petersen wrote:That only applies when you actually have " in the string. I think both have their uses.IMHO r"" is better than `` for the simple reason that typing `` is extremely annoying on non-US keyboards.`` is better because you don't have to escape ".
Apr 30 2012
On 2012-04-30 22:03, Alex Rønne Petersen wrote:On 30-04-2012 21:42, Jacob Carlborg wrote:`` can be used for that. ` is good because it's a different delimiter compared to r"" or "". -- /Jacob CarlborgWhen is r"" a better use than ``? We already have the regular "".You don't have escape sequences inside r"", so they can be useful if you have backslashes in your string.
May 01 2012
On 01-05-2012 13:22, Jacob Carlborg wrote:On 2012-04-30 22:03, Alex Rønne Petersen wrote:It *can*, but it's annoying on non-US keyboards, which was my original point. -- - AlexOn 30-04-2012 21:42, Jacob Carlborg wrote:`` can be used for that. ` is good because it's a different delimiter compared to r"" or "".When is r"" a better use than ``? We already have the regular "".You don't have escape sequences inside r"", so they can be useful if you have backslashes in your string.
May 01 2012
On 2012-05-01 16:28, Alex Rønne Petersen wrote:It *can*, but it's annoying on non-US keyboards, which was my original point.Well, I don't agree. -- /Jacob Carlborg
May 01 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I guess the underlying problem is inability to formulate the target state of the language with specified relations between different components. Being looking at the language since late 2011 I found problematic to know the language as a whole. When a newcomer looks for information he either gets a common overview "native efficiency, ..." at dlang.org with (outdated) documentation or videos on youtube which explains how scope(xxx) beats exceptions and templates are superior to that in C++ and similar posts in the web, let alone toolchain lack complaints. My comment was provoked mainly by http://forum.dlang.org/thread/vwpzirpppabcgylmvpsx forum.dlang.org discussion (D3 idea). You ask which features are redundant or not significant, but this depends on how features are integrated in the rest of language and without clear and completed vision there is no answer. And please remember, that each of D member has its own (biased) information about D and what to do. The language is moving and it is hard to reveal how any change will affect other components. Even if you found a particular item redundant there is no guarantee that the situation will not change in future. "usability" and C performance) view D as a ship which sails in unknown direction with lots of holes (look at bugzilla proposals how to make a language) and what I found the most dreaded is that the direction of the ship movement today is determined by which hole was fixed yesterday. So, you are free to ask ship's crew about what hole and how to fix and expect that it will tomorrow bring ship to a better place, but without final destination this brownian movement may theoretically last infinitely, but of course, in practice it will lead either to ship crashing, departure of sailors or finally targeting an unexpected place with unsatisfactory result.
Apr 28 2012
On Saturday, 28 April 2012 at 20:49:33 UTC, Maxim Fomin wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I guess the underlying problem is inability to formulate the target state of the language with specified relations between different components. Being looking at the language since late 2011 I found problematic to know the language as a whole. When a newcomer looks for information he either gets a common overview "native efficiency, ..." at dlang.org with (outdated) documentation or videos on youtube which explains how scope(xxx) beats exceptions and templates are superior to that in C++ and similar posts in the web, let alone toolchain lack complaints. My comment was provoked mainly by http://forum.dlang.org/thread/vwpzirpppabcgylmvpsx forum.dlang.org discussion (D3 idea). You ask which features are redundant or not significant, but this depends on how features are integrated in the rest of language and without clear and completed vision there is no answer. And please remember, that each of D member has its own (biased) information about D and what to do. The language is moving and it is hard to reveal how any change will affect other components. Even if you found a particular item redundant there is no guarantee that the situation will not change in future. "usability" and C performance) view D as a ship which sails in unknown direction with lots of holes (look at bugzilla proposals how to make a language) and what I found the most dreaded is that the direction of the ship movement today is determined by which hole was fixed yesterday. So, you are free to ask ship's crew about what hole and how to fix and expect that it will tomorrow bring ship to a better place, but without final destination this brownian movement may theoretically last infinitely, but of course, in practice it will lead either to ship crashing, departure of sailors or finally targeting an unexpected place with unsatisfactory result.
Apr 28 2012
On Saturday, 28 April 2012 at 20:49:33 UTC, Maxim Fomin wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:That's a very well worded post. That's one more reason why the most important thing imho is to have the current feature set stabilized, and not adding or removing features every other month, because we don't have enough experience with D to be certain such feature is redundant. This kind of experience can only be gained with feedback from hundreds or thousands of users, and there aren't that many users in this newsgroup. D is large enough that I'm pretty sure no two programmers use the same features. That's why we have so different answers to the question "which features is useless ?". Yet every programmer has his favorite feature that saves his ass at one point or another, and that's why everybody finds it's a joy to use. Were it missing, someone would complain. I'm pretty confident that in a sufficiently large program, nearly every single feature of the language will be put to good use. Now what people don't like is when features or Phobos don't work as expected, I suppose that's what you call holes. And that's another matter. I've browsed through hundreds of bug reports last week, and I could see many many features don't work as expected. And that's the most important problem in my opinion. That's where most of the efforts should be put.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I guess the underlying problem is inability to formulate the target state of the language with specified relations between different components. Being looking at the language since late 2011 I found problematic to know the language as a whole. When a newcomer looks for information he either gets a common overview "native efficiency, ..." at dlang.org with (outdated) documentation or videos on youtube which explains how scope(xxx) beats exceptions and templates are superior to that in C++ and similar posts in the web, let alone toolchain lack complaints. My comment was provoked mainly by http://forum.dlang.org/thread/vwpzirpppabcgylmvpsx forum.dlang.org discussion (D3 idea). You ask which features are redundant or not significant, but this depends on how features are integrated in the rest of language and without clear and completed vision there is no answer. And please remember, that each of D member has its own (biased) information about D and what to do. The language is moving and it is hard to reveal how any change will affect other components. Even if you found a particular item redundant there is no guarantee that the situation will not change in future. "usability" and C performance) view D as a ship which sails in unknown direction with lots of holes (look at bugzilla proposals how to make a language) and what I found the most dreaded is that the direction of the ship movement today is determined by which hole was fixed yesterday. So, you are free to ask ship's crew about what hole and how to fix and expect that it will tomorrow bring ship to a better place, but without final destination this brownian movement may theoretically last infinitely, but of course, in practice it will lead either to ship crashing, departure of sailors or finally targeting an unexpected place with unsatisfactory result.
Apr 28 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:What's your list?I think most the responses to this thread are insane. But, there is one thing I don't think D needs: new. I'm pretty sure it could be done in the library now that we have robust templates, which I think would open up some nice things. Suppose: module std.typecons; NotNull!T new(T, Args...)(Args args) { return assumeNotNull(core.gc.new!T(args)); } module core.gc; T new(T, Args...)(Args args) { // implement the new we know now } And so on, then you could get new allocators just by changing which module you import new from. We could kinda sorta do it now, but it wouldn't be as consistent, and of course, the name "new" is unavailable.
Apr 28 2012
On Saturday, April 28, 2012 23:20:42 Adam D. Ruppe wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:LOL. Yeah. Many of them involve completely gutted pieces of the language, and very few discuss "redundant" features like Walter mentioned. - Jonathan M DavisWhat's your list?I think most the responses to this thread are insane.
Apr 28 2012
On 28-04-2012 23:20, Adam D. Ruppe wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:OK, so while in general I agree that 'new' shouldn't be tied to the GC by default, I don't think your example of swapping allocators through imports is a good idea at all. The reason is simple: More often than not, it never *is* as simple as just changing an import. Some allocators use stack allocation, some use C heap allocation, some use the druntime GC, some use the libgc library, ... All of these need different treatment of the allocated memory, so I don't think there is much to be gained here. -- - AlexWhat's your list?I think most the responses to this thread are insane. But, there is one thing I don't think D needs: new. I'm pretty sure it could be done in the library now that we have robust templates, which I think would open up some nice things. Suppose: module std.typecons; NotNull!T new(T, Args...)(Args args) { return assumeNotNull(core.gc.new!T(args)); } module core.gc; T new(T, Args...)(Args args) { // implement the new we know now } And so on, then you could get new allocators just by changing which module you import new from. We could kinda sorta do it now, but it wouldn't be as consistent, and of course, the name "new" is unavailable.
Apr 29 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Here's my list: - Properties. They add no value and just start pointless discussions about what should and shouldn't be a property. - UFCS. It's just sugar, but adds complexity. - const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time. - opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit. Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs. That's all I can think of for now.
Apr 28 2012
On Sat, Apr 28, 2012 at 11:42:31PM +0200, Peter Alexander wrote: [...]- UFCS. It's just sugar, but adds complexity.On the contrary, it's a major helper for writing generic code. In my new AA implementation, I use UFCS to provide a default toHash function for all types that don't already provide one. Without UFCS, this would require lots of ugly hacks and constraints on how user code can provide custom hash functions. (Due to the way D overloading works, UFCS is currently the only way to provide a default function without causing a conflict at compile-time.)- const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time.Yeah they are complex, but they also open ways for powerful optimizations by the compiler. Though I do have to say that inout needs some serious reconsideration, since the way they work currently is ambiguous when you have more than one inout argument, or when you have a delegate parameter with inout arguments.- opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit.Wrong. It's a powerful tool for building runtime dynamic class loading. It allows you to write generic code that Just Works without having to special-case them for statically-known classes vs. dynamic classes. If anything, I'd argue for *more* similar features that let you write generic code that integrates seamlessly into the language. Just because it's been used (arguably abused) for things like making roman numerals or vector swizzling, doesn't mean it's a bad feature.Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs.[...] Yikes!! Please don't reintroduce that monstrous -> operator from C++! (Besides, most of the time idiomatic D code doesn't even need pointers.) T -- If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. Chesterton
Apr 28 2012
On Saturday, 28 April 2012 at 21:58:47 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 11:42:31PM +0200, Peter Alexander wrote: [...]The problem there is that toHash is a member function. That UFCS is helpful in working around other problems in D is not a good argument for its existence IMO. To be honest, I don't like the idea of member functions at all. Having two syntaxes for calling a function is the core problem, and UFCS is just an extra complication on top of it to try and mitigate the original problem. f(x) ---> x.f() is not progress in language design.- UFCS. It's just sugar, but adds complexity.On the contrary, it's a major helper for writing generic code. In my new AA implementation, I use UFCS to provide a default toHash function for all types that don't already provide one. Without UFCS, this would require lots of ugly hacks and constraints on how user code can provide custom hash functions. (Due to the way D overloading works, UFCS is currently the only way to provide a default function without causing a conflict at compile-time.)In theory. IMO the amount of time you spend trying to please the type system could have been better spent optimizing your code manually. No code I have ever written would benefit significantly from these potential optimisations. For example, one optimisation is that pure function calls could be hoisted out of loops. Great, except that if that function call had any significant cost whatsoever, I would have already done that optimisation myself.- const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time.Yeah they are complex, but they also open ways for powerful optimizations by the compiler.It's my opinion. You are free to disagree, but opinions can't be wrong. I've seen no good uses of opDispatch so far. If you can point me towards some code that justifies its use then please let me know about it.- opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit.Wrong.
Apr 28 2012
Peter Alexander:f(x) ---> x.f() is not progress in language design.I used to think the same. But Haskell offers "." and $ to chain In D UCFS is almost equally useful to turn nesting of function calls in a more readable chain. In functional-style code this makes a lot of difference, turning: foo(bar(copy(baz(a), spam(b)))) Into: baz(a).copy(b.spam()).bar().foo() When I see 3+ nested parentheses I find it hard to read the expression. While a chain is easy to read.In theory. IMO the amount of time you spend trying to please the type system could have been better spent optimizing your code manually. No code I have ever written would benefit significantly from these potential optimisations. For example, one optimisation is that pure function calls could be hoisted out of loops. Great, except that if that function call had any significant cost whatsoever, I would have already done that optimisation myself.I used to write lot of D1 code too, and I've seen that managing D2 const-related issues slows down significantly my coding compared to D1 coding, so undeniably they have a cost. But in D the main purpose of "pure" is not as optimization tool, but more as a tool to enforce a better coding style, that makes code understanding (and testing simpler), and helps avoid some bugs, coming from using variables from outer scopes. Bye, bearophile
Apr 28 2012
On Saturday, 28 April 2012 at 23:29:35 UTC, bearophile wrote:Peter Alexander:What D does and what Haskell does are very different things. D has (at least) two types of functions: free functions and member functions. UFCS makes free functions look like member functions. In Haskell, $ just gives you a way of re-ordering precedence -- it doesn't hide anything. This matters because UFCS in D is deceitful. It makes you think the free function is a member function when it is not. struct Foo { void bar() {} } void baz(Foo f) {} Foo f; f.bar(); // ok f.baz(); // ok, looks like baz is a member function auto pbar = &Foo.bar; // ok auto pbaz = &Foo.baz; // error! IMO, D would be better with Haskell's function calling syntax (of course, this would require many, many other syntactical changes).f(x) ---> x.f() is not progress in language design.I used to think the same. But Haskell offers "." and $ to chain operator. In D UCFS is almost equally useful to turn nesting of function calls in a more readable chain. In functional-style code this makes a lot of difference, turning: foo(bar(copy(baz(a), spam(b)))) Into: baz(a).copy(b.spam()).bar().foo() When I see 3+ nested parentheses I find it hard to read the expression. While a chain is easy to read.But in D the main purpose of "pure" is not as optimization tool, but more as a tool to enforce a better coding style, that makes code understanding (and testing simpler), and helps avoid some bugs, coming from using variables from outer scopes.True, but I'm quite happy to write pure functions without the static checking. I do not believe that the safety provided by the static checks outweighs the development cost of ensuring you have the correct qualifiers everywhere.
Apr 28 2012
On 29-04-2012 01:41, Peter Alexander wrote:On Saturday, 28 April 2012 at 23:29:35 UTC, bearophile wrote:In my experience, pure is only hard to use in D due to the runtime and standard library not being properly annotated. I don't think anything is wrong with the language feature itself. -- - AlexPeter Alexander:What D does and what Haskell does are very different things. D has (at least) two types of functions: free functions and member functions. UFCS makes free functions look like member functions. In Haskell, $ just gives you a way of re-ordering precedence -- it doesn't hide anything. This matters because UFCS in D is deceitful. It makes you think the free function is a member function when it is not. struct Foo { void bar() {} } void baz(Foo f) {} Foo f; f.bar(); // ok f.baz(); // ok, looks like baz is a member function auto pbar = &Foo.bar; // ok auto pbaz = &Foo.baz; // error! IMO, D would be better with Haskell's function calling syntax (of course, this would require many, many other syntactical changes).f(x) ---> x.f() is not progress in language design.I used to think the same. But Haskell offers "." and $ to chain UCFS is almost equally useful to turn nesting of function calls in a more readable chain. In functional-style code this makes a lot of difference, turning: foo(bar(copy(baz(a), spam(b)))) Into: baz(a).copy(b.spam()).bar().foo() When I see 3+ nested parentheses I find it hard to read the expression. While a chain is easy to read.But in D the main purpose of "pure" is not as optimization tool, but more as a tool to enforce a better coding style, that makes code understanding (and testing simpler), and helps avoid some bugs, coming from using variables from outer scopes.True, but I'm quite happy to write pure functions without the static checking. I do not believe that the safety provided by the static checks outweighs the development cost of ensuring you have the correct qualifiers everywhere.
Apr 29 2012
On Saturday, 28 April 2012 at 23:41:29 UTC, Peter Alexander wrote:Maybe you don't feel the benefit because you have less bugs in multithreaded applications than you would without, but you can't really know unless you do write the same code without ? Or something like that. :o) Anyway, I have the feeling that it's very hard to quantify the benefits of adding purity vs not having it. The benefits are both very theoretical, and practically verified in functional languages everyday. But knowing that the compiler *guarantees* certain properties and that some classes of errors cannot happen helps coding with a certain peace of mind, i.e you *know* that some bad things can't happen. So it's a little pain to satisfy the static checking of the compiler, but it's still much better than having to debug random race conditions that happen once in a while in production and are thus very hard to reproduce, and it does certainly help when you have to *ensure* that your critical code can never hang.But in D the main purpose of "pure" is not as optimization tool, but more as a tool to enforce a better coding style, that makes code understanding (and testing simpler), and helps avoid some bugs, coming from using variables from outer scopes.True, but I'm quite happy to write pure functions without the static checking. I do not believe that the safety provided by the static checks outweighs the development cost of ensuring you have the correct qualifiers everywhere.
Apr 29 2012
On 28-04-2012 23:59, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 11:42:31PM +0200, Peter Alexander wrote: [...]I don't know of any production compilers that make significant use of such annotations in any language. These qualifiers look nice in theory, but have little practical value other than making it easier to reason about code. I don't think they should go away, just sayin'. (BTW, I think nothing is wrong with pure.)- UFCS. It's just sugar, but adds complexity.On the contrary, it's a major helper for writing generic code. In my new AA implementation, I use UFCS to provide a default toHash function for all types that don't already provide one. Without UFCS, this would require lots of ugly hacks and constraints on how user code can provide custom hash functions. (Due to the way D overloading works, UFCS is currently the only way to provide a default function without causing a conflict at compile-time.)- const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time.Yeah they are complex, but they also open ways for powerful optimizations by the compiler.Though I do have to say that inout needs some serious reconsideration, since the way they work currently is ambiguous when you have more than one inout argument, or when you have a delegate parameter with inout arguments.-- - Alex- opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit.Wrong. It's a powerful tool for building runtime dynamic class loading. It allows you to write generic code that Just Works without having to special-case them for statically-known classes vs. dynamic classes. If anything, I'd argue for *more* similar features that let you write generic code that integrates seamlessly into the language. Just because it's been used (arguably abused) for things like making roman numerals or vector swizzling, doesn't mean it's a bad feature.Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs.[...] Yikes!! Please don't reintroduce that monstrous -> operator from C++! (Besides, most of the time idiomatic D code doesn't even need pointers.) T
Apr 29 2012
On 29 April 2012 00:42, Peter Alexander <peter.alexander.au gmail.com>wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:I disagree with every one of those points, except maybe 'shared', which seems like a good idea in theory, but I think it's completely broken (every interaction requires an explicit cast, and there is no facility for transfer of ownership, which is a VERY common operation in my experience)Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Here's my list: - Properties. They add no value and just start pointless discussions about what should and shouldn't be a property. - UFCS. It's just sugar, but adds complexity. - const/immutable/inout/shared/**pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time. - opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit. Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs. That's all I can think of for now.
Apr 28 2012
On 29-04-2012 00:30, Manu wrote:On 29 April 2012 00:42, Peter Alexander <peter.alexander.au gmail.com <mailto:peter.alexander.au gmail.com>> wrote: On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? Here's my list: - Properties. They add no value and just start pointless discussions about what should and shouldn't be a property. - UFCS. It's just sugar, but adds complexity. - const/immutable/inout/shared/__pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time. - opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit. Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs. That's all I can think of for now. I disagree with every one of those points, except maybe 'shared', which seems like a good idea in theory, but I think it's completely broken (every interaction requires an explicit cast, and there is no facility for transfer of ownership, which is a VERY common operation in my experience)For shared to be useful, every function you call on/with a shared object/value must be templatized. This may be nice if most of the code you write is template-rich, but like anything else, templates are not a silver bullet. IMHO shared is heavily biased in its design, which is bad. -- - Alex
Apr 29 2012
On 04/28/2012 11:42 PM, Peter Alexander wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:- UFCS: The complexity comes from having multiple function invocation syntaxes. UFCS actually makes that situation better without adding a lot of complexity to the compiler implementation. - const/immutable/shared/pure shared: The fact that everything that is not marked as shared is actually thread-local is extremely important. I think most other imperative languages got this wrong. But if shared is explicit in the type system, immutable really should be explicit too. The sad part is that the qualifiers don't play nicely with reference types at the moment. - opDispatch This is useful and of significant value if used the right way. I hope you are not actually serious about that '->' part.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Here's my list: - Properties. They add no value and just start pointless discussions about what should and shouldn't be a property. - UFCS. It's just sugar, but adds complexity. - const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time. - opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit. Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs. That's all I can think of for now.
Apr 28 2012
On Saturday, 28 April 2012 at 22:33:08 UTC, Timon Gehr wrote:- UFCS: The complexity comes from having multiple function invocation syntaxes. UFCS actually makes that situation better without adding a lot of complexity to the compiler implementation.Exactly. The problem is having multiple function invocation syntaxes. That's one source of complexity, and UFCS add another in attempt to reduce the first cause.- const/immutable/shared/pure shared: The fact that everything that is not marked as shared is actually thread-local is extremely important. I think most other imperative languages got this wrong. But if shared is explicit in the type system, immutable really should be explicit too. The sad part is that the qualifiers don't play nicely with reference types at the moment.I agree with thread-local by default, but that is separate from shared.- opDispatch This is useful and of significant value if used the right way.Can you give me an example of it being used the right way?I hope you are not actually serious about that '->' part.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.
Apr 28 2012
On Saturday, 28 April 2012 at 23:11:17 UTC, Peter Alexander wrote:On Saturday, 28 April 2012 at 22:33:08 UTC, Timon Gehr wrote:vector swizzling! :D- UFCS: The complexity comes from having multiple function invocation syntaxes. UFCS actually makes that situation better without adding a lot of complexity to the compiler implementation.Exactly. The problem is having multiple function invocation syntaxes. That's one source of complexity, and UFCS add another in attempt to reduce the first cause.- const/immutable/shared/pure shared: The fact that everything that is not marked as shared is actually thread-local is extremely important. I think most other imperative languages got this wrong. But if shared is explicit in the type system, immutable really should be explicit too. The sad part is that the qualifiers don't play nicely with reference types at the moment.I agree with thread-local by default, but that is separate from shared.- opDispatch This is useful and of significant value if used the right way.Can you give me an example of it being used the right way?I hope you are not actually serious about that '->' part.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.
Apr 28 2012
Peter Alexander wrote:It can be very useful for jQuery/JSON style dynamic objects: import std.variant, std.stdio; struct Dynamic { Variant[string] vars; void opDispatch(string key)() property { return vars[key]; } void opDispatch(string key, T)(T value) property { vars[key] = value; } } void main() { auto foo = Dynamic(); foo.a = "A"; foo.b = 11; writefln("%s, %s", foo.a, foo.b); }- opDispatch This is useful and of significant value if used the right way.Can you give me an example of it being used the right way?Craziness. What could you possibly gain is there in forcing a pointer distinction at every point that it's used? We already declared the variable as a pointer, we don't need to be reminded of that fact at every line.I hope you are not actually serious about that '->' part.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.
Apr 28 2012
On Saturday, 28 April 2012 at 23:37:14 UTC, F i L wrote:Peter Alexander wrote:This is a perfect example of misuse. Glancing at that code, it looks like foo has two member variables. It is also not clear that each access involves a hash-table lookup. Why abuse well-understood syntax when there are simpler ways to solve the problem?It can be very useful for jQuery/JSON style dynamic objects: import std.variant, std.stdio; struct Dynamic { Variant[string] vars; void opDispatch(string key)() property { return vars[key]; } void opDispatch(string key, T)(T value) property { vars[key] = value; } } void main() { auto foo = Dynamic(); foo.a = "A"; foo.b = 11; writefln("%s, %s", foo.a, foo.b); }- opDispatch This is useful and of significant value if used the right way.Can you give me an example of it being used the right way?It matters when you have things that imitate pointers (e.g. smart pointers). Those will have their own members, separate from the pointee's members, so ptr.foo could refer to the smart pointer's members or the pointee's members.Craziness. What could you possibly gain is there in forcing a pointer distinction at every point that it's used? We already declared the variable as a pointer, we don't need to be reminded of that fact at every line.I hope you are not actually serious about that '->' part.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.
Apr 28 2012
On Saturday, 28 April 2012 at 23:54:36 UTC, Peter Alexander wrote:It matters when you have things that imitate pointers (e.g. smart pointers). Those will have their own members, separate from the pointee's members, so ptr.foo could refer to the smart pointer's members or the pointee's members.So basically, for your very specific issue, you want to ditch a syntax that 99% of people actually prefer. I must say you are the very first person I see *anywhere* who actually complains about the . notation and would rather go back to ->.
Apr 28 2012
On Sunday, April 29, 2012 01:54:35 Peter Alexander wrote:On Saturday, 28 April 2012 at 23:37:14 UTC, F i L wrote:For better or worse, the solution for smart pointers in D would be to use opDispatch, but it _does_ still mean that the type pointed to can't have any of the same functions as the smart pointer (or at least, they would have to be called differently, since . would use opDispatch and therefore use the smart pointer's function), so you _do_ lose something over the -> syntax here. However, the overall gain is usability probably still outweighs that. I wouldn't exactly have been heartbroken if -> had been in D, but simplicity of not needing it can be very nice - and it can be invaluable in the case of templates, because then you don't have to distinguish between structs, pointers to structs, and classes when calling functions on them. - Jonathan M DavisPeter Alexander wrote:It matters when you have things that imitate pointers (e.g. smart pointers). Those will have their own members, separate from the pointee's members, so ptr.foo could refer to the smart pointer's members or the pointee's members.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.Craziness. What could you possibly gain is there in forcing a pointer distinction at every point that it's used? We already declared the variable as a pointer, we don't need to be reminded of that fact at every line.
Apr 28 2012
On 29.04.2012 4:31, Jonathan M Davis wrote:On Sunday, April 29, 2012 01:54:35 Peter Alexander wrote:*cough* alias this *cough* but it _does_ still mean that the type pointed to can't have anyOn Saturday, 28 April 2012 at 23:37:14 UTC, F i L wrote:For better or worse, the solution for smart pointers in D would be to use opDispatch,Peter Alexander wrote:It matters when you have things that imitate pointers (e.g. smart pointers). Those will have their own members, separate from the pointee's members, so ptr.foo could refer to the smart pointer's members or the pointee's members.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.Craziness. What could you possibly gain is there in forcing a pointer distinction at every point that it's used? We already declared the variable as a pointer, we don't need to be reminded of that fact at every line.of the same functions as the smart pointer (or at least, they would have to be called differently, since . would use opDispatch and therefore use the smart pointer's function), so you _do_ lose something over the -> syntax here. However, the overall gain is usability probably still outweighs that. I wouldn't exactly have been heartbroken if -> had been in D, but simplicity of not needing it can be very nice - and it can be invaluable in the case of templates, because then you don't have to distinguish between structs, pointers to structs, and classes when calling functions on them. - Jonathan M Davis-- Dmitry Olshansky
Apr 28 2012
On Sunday, April 29, 2012 09:53:15 Dmitry Olshansky wrote:On 29.04.2012 4:31, Jonathan M Davis wrote:That's not necessarily a good idea, depending on how it's used. You want to avoid having the smart pointer implicitly convert to what it holds such that a reference to it leaks. If you're dealing with a pointer to a struct, and alias this aliases to the struct (rather than the pointer), then you're okay. But if you're dealing with a class, you don't have that option. So, alias this ends up leaking a reference to the class, which defeats the purpose of the smart pointer. You have the same problem if alias this aliases to the pointer rather than what's pointed to. But regardless of whether you use alias this or opDispatch, you have the same problem with regards to ->. In C++, . would be used to call the smart pointer's functions, and -> would be used to call functions on the object pointed to. In D, the two aren't distinguished - both use . - so you can't have any functions on the type pointed to which conflict with the smart pointer's functions, or you won't be able to call them (unless another way to call them is provided somehow). So, it's definitely something that C++ does better with as far as that goes. - Jonathan M DavisFor better or worse, the solution for smart pointers in D would be to use opDispatch,*cough* alias this *cough*
Apr 28 2012
On 29.04.2012 10:42, Jonathan M Davis wrote:On Sunday, April 29, 2012 09:53:15 Dmitry Olshansky wrote:Point taken.On 29.04.2012 4:31, Jonathan M Davis wrote:That's not necessarily a good idea, depending on how it's used. You want to avoid having the smart pointer implicitly convert to what it holds such that a reference to it leaks. If you're dealing with a pointer to a struct, and alias this aliases to the struct (rather than the pointer), then you're okay. But if you're dealing with a class, you don't have that option. So, alias this ends up leaking a reference to the class, which defeats the purpose of the smart pointer. You have the same problem if alias this aliases to the pointer rather than what's pointed to.For better or worse, the solution for smart pointers in D would be to use opDispatch,*cough* alias this *cough*But regardless of whether you use alias this or opDispatch, you have the same problem with regards to ->. In C++, . would be used to call the smart pointer's functions, and -> would be used to call functions on the object pointed to. In D, the two aren't distinguished - both use . - so you can't have any functions on the type pointed to which conflict with the smart pointer's functions, or you won't be able to call them (unless another way to call them is provided somehow). So, it's definitely something that C++ does better with as far as that goes.So you just need not to have any _member_ functions on smart pointer? Just use free functions that take SmartPointer!T. UFCS may also lend a hand if T and SmartPointer do not have ambiguous funcs. -- Dmitry Olshansky
Apr 29 2012
On Sunday, April 29, 2012 16:28:23 Dmitry Olshansky wrote:On 29.04.2012 10:42, Jonathan M Davis wrote:That could work (though they'd obviously have to be in the same module as the smart pointer - not exactly an onerous requirement - in order to be able to access its private members). - Jonathan M DavisBut regardless of whether you use alias this or opDispatch, you have the same problem with regards to ->. In C++, . would be used to call the smart pointer's functions, and -> would be used to call functions on the object pointed to. In D, the two aren't distinguished - both use . - so you can't have any functions on the type pointed to which conflict with the smart pointer's functions, or you won't be able to call them (unless another way to call them is provided somehow). So, it's definitely something that C++ does better with as far as that goes.So you just need not to have any _member_ functions on smart pointer? Just use free functions that take SmartPointer!T. UFCS may also lend a hand if T and SmartPointer do not have ambiguous funcs.
Apr 29 2012
On Saturday, 28 April 2012 at 23:54:36 UTC, Peter Alexander wrote:On Saturday, 28 April 2012 at 23:37:14 UTC, F i L wrote:It's not abuse, it's design. That's why I called the type "Dynamic" so the user has an idea about what it is. You could make your same arguments against ever using a Variant object. When you have to manipulate a DOM or XML tree, there's reason why people prefer languages that syntactically interface with those dynamic structure very well. D simply powerful enough to provide a way for programmers to do both. Btw, it's just as unclear that any property (or function) doesn't look through a hash-table or any other number of performance pitfalls if used without any insight into _how_ to use it. This is why we have documentation for libraries, it's impractical cater the language to the idea that coders wont understand the objects their working with to a basic degree.Peter Alexander wrote:This is a perfect example of misuse. Glancing at that code, it looks like foo has two member variables. It is also not clear that each access involves a hash-table lookup. Why abuse well-understood syntax when there are simpler ways to solve the problem?It can be very useful for jQuery/JSON style dynamic objects: import std.variant, std.stdio; struct Dynamic { Variant[string] vars; void opDispatch(string key)() property { return vars[key]; } void opDispatch(string key, T)(T value) property { vars[key] = value; } } void main() { auto foo = Dynamic(); foo.a = "A"; foo.b = 11; writefln("%s, %s", foo.a, foo.b); }- opDispatch This is useful and of significant value if used the right way.Can you give me an example of it being used the right way?SomeDude said this best. This is far the common case, and the language shouldn't force everyone to pay for this situation.It matters when you have things that imitate pointers (e.g. smart pointers). Those will have their own members, separate from the pointee's members, so ptr.foo could refer to the smart pointer's members or the pointee's members.Craziness. What could you possibly gain is there in forcing a pointer distinction at every point that it's used? We already declared the variable as a pointer, we don't need to be reminded of that fact at every line.I hope you are not actually serious about that '->' part.I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.
Apr 28 2012
Typos. Typos everywhere :S I'm sure you get my meaning.
Apr 28 2012
"Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:nvvuxboigxxfdqfhyftw forum.dlang.org...To be honest, I don't like the idea of member functions at all. Having two syntaxes for calling a function is the core problem, and UFCS is just an extra complication on top of it to try and mitigate the original problem. f(x) ---> x.f() is not progress in language design.[...]I'm serious. I don't like overloaded syntax. foo.bar shouldn't also mean (*foo).bar -- it causes confusion and introduces ambiguities when either could work. Combine this with opDispatch, UFCS and function overloading and your in for some nasty headaches.[...]Glancing at that code, it looks like foo has two member variables. It is also not clear that each access involves a hash-table lookup.It sounds like you just simply don't like abstractions. I can understand that (although I don't agree with it), but it always puzzles me why such people even try to use high-level langauges at all instead of just binary machine code. And for the record, I've *never* seen anyone confused by foo.bar syntax being used on reference types.
Apr 29 2012
On 2012-04-28 23:42, Peter Alexander wrote:Here's my list: - Properties. They add no value and just start pointless discussions about what should and shouldn't be a property. - UFCS. It's just sugar, but adds complexity. - const/immutable/inout/shared/pure. These add massive complexity to the language for little (IMO) benefit. When I do multi-threading, I usually have to resort to casting. Maybe these will improve with time. - opDispatch. I think it just promotes sloppy, obfuscated code for minor syntactical benefit. Member access through pointers should require -> like in C++ so that you can overload it for smart pointer/reference ADTs. That's all I can think of for now.I love all these features beside the attributes. -- /Jacob Carlborg
Apr 29 2012
Le 28/04/2012 20:47, Walter Bright a écrit :Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?OK longer answer. - is is messed up. It is a massive hack and have to be rationalized. - version is a bad version of static if. The static if part of the version must go. - comma expression is confusing and have very little benefice. - out arguments. We can return tuples, out argument is going backward in history. - many array properties (.sort for instance) are useless and would be way better as libs.
Apr 28 2012
On Saturday, 28 April 2012 at 21:51:42 UTC, deadalnix wrote:- out arguments. We can return tuples, out argument is going backward in history. - many array properties (.sort for instance) are useless and would be way better as libs.What happens the day the language is actually fit for embedded programming, and you don't want to have to link against Phobos because it's too big ?
Apr 28 2012
On Sat, Apr 28, 2012 at 11:57:46PM +0200, SomeDude wrote:On Saturday, 28 April 2012 at 21:51:42 UTC, deadalnix wrote:We need to fix things so that using a single feature in Phobos will not pull in the entire library. That's an implementation issue, not a language issue. T -- LINUX = Lousy Interface for Nefarious Unix Xenophobes.- out arguments. We can return tuples, out argument is going backward in history. - many array properties (.sort for instance) are useless and would be way better as libs.What happens the day the language is actually fit for embedded programming, and you don't want to have to link against Phobos because it's too big ?
Apr 28 2012
On Saturday, 28 April 2012 at 22:04:26 UTC, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 11:57:46PM +0200, SomeDude wrote:It is, but it's actually a very difficult implementation issue. And what I currently see is, many Phobos bugs are simply not corrected, while DMD bugs actually are. It seems that noone but Andrei is working on Phobos. And he is only part time on it. Also, ranges are cool, but they are big. And not everyone wants to have to huge ranges when they can use simpler, and arguably faster arrays. I'm not very satisfied with the current state of Phobos. Being the standard library, it should *work*. Yet it seems to me some things simply don't work at all. The new regex, for instance, I've yet to compile anything with it. The author argues the CTFE is broken, but even the runtime regex doesn't compile. That's not acceptable in a standard library. So before thinking about removing these little features from the core language, thoses issues with Phobos must first be solved.What happens the day the language is actually fit for embedded programming, and you don't want to have to link against Phobos because it's too big ?We need to fix things so that using a single feature in Phobos will not pull in the entire library. That's an implementation issue, not a language issue. T
Apr 28 2012
On Sat, Apr 28, 2012 at 11:58:19PM +0200, deadalnix wrote: [...]- is is messed up. It is a massive hack and have to be rationalized.As I said in another thread, the _functionality_ of various is() expressions are very useful and should be kept. But the _syntax_ is completely b0rked and needs some serious redesign.- version is a bad version of static if. The static if part of the version must go.What's your proposal?- comma expression is confusing and have very little benefice.+1. I say that D3 should drop the comma operator. Esp. when doing so will open up the way for having native syntax for tuples. Needing to resort to Phobos to have a way to name a compiler-supported type is backwards and silly.- out arguments. We can return tuples, out argument is going backward in history.Not when there's no way to name tuples without resorting to Phobos (or copy-n-paste Phobos code).- many array properties (.sort for instance) are useless and would be way better as libs.Yeah, .sort is redundant, and besides shouldn't be an array "property" to begin with. T -- What's a "hot crossed bun"? An angry rabbit.
Apr 28 2012
Le 29/04/2012 00:04, H. S. Teoh a écrit :On Sat, Apr 28, 2012 at 11:58:19PM +0200, deadalnix wrote: [...]That is what I meant.- is is messed up. It is a massive hack and have to be rationalized.As I said in another thread, the _functionality_ of various is() expressions are very useful and should be kept. But the _syntax_ is completely b0rked and needs some serious redesign.version(foobar) returning a boolean at compile time for instance.- version is a bad version of static if. The static if part of the version must go.What's your proposal?See how both go together. Remove comma expression, get a nice tuple syntax, and then remove out parameter seems a nice way to go.- comma expression is confusing and have very little benefice.+1. I say that D3 should drop the comma operator. Esp. when doing so will open up the way for having native syntax for tuples. Needing to resort to Phobos to have a way to name a compiler-supported type is backwards and silly.- out arguments. We can return tuples, out argument is going backward in history.Not when there's no way to name tuples without resorting to Phobos (or copy-n-paste Phobos code).
Apr 28 2012
On 29-04-2012 00:04, H. S. Teoh wrote:On Sat, Apr 28, 2012 at 11:58:19PM +0200, deadalnix wrote: [...]Let's not forget .reverse. Why these are properties (and .dup/.idup) is seriously beyond me..... -- - Alex- is is messed up. It is a massive hack and have to be rationalized.As I said in another thread, the _functionality_ of various is() expressions are very useful and should be kept. But the _syntax_ is completely b0rked and needs some serious redesign.- version is a bad version of static if. The static if part of the version must go.What's your proposal?- comma expression is confusing and have very little benefice.+1. I say that D3 should drop the comma operator. Esp. when doing so will open up the way for having native syntax for tuples. Needing to resort to Phobos to have a way to name a compiler-supported type is backwards and silly.- out arguments. We can return tuples, out argument is going backward in history.Not when there's no way to name tuples without resorting to Phobos (or copy-n-paste Phobos code).- many array properties (.sort for instance) are useless and would be way better as libs.Yeah, .sort is redundant, and besides shouldn't be an array "property" to begin with. T
Apr 29 2012
Le 29/04/2012 22:40, Alex Rønne Petersen a écrit :On 29-04-2012 00:04, H. S. Teoh wrote:Why they are not provided as lib but by the core language ?On Sat, Apr 28, 2012 at 11:58:19PM +0200, deadalnix wrote: [...]Let's not forget .reverse. Why these are properties (and .dup/.idup) is seriously beyond me.....- is is messed up. It is a massive hack and have to be rationalized.As I said in another thread, the _functionality_ of various is() expressions are very useful and should be kept. But the _syntax_ is completely b0rked and needs some serious redesign.- version is a bad version of static if. The static if part of the version must go.What's your proposal?- comma expression is confusing and have very little benefice.+1. I say that D3 should drop the comma operator. Esp. when doing so will open up the way for having native syntax for tuples. Needing to resort to Phobos to have a way to name a compiler-supported type is backwards and silly.- out arguments. We can return tuples, out argument is going backward in history.Not when there's no way to name tuples without resorting to Phobos (or copy-n-paste Phobos code).- many array properties (.sort for instance) are useless and would be way better as libs.Yeah, .sort is redundant, and besides shouldn't be an array "property" to begin with. T
Apr 29 2012
On Sun, Apr 29, 2012 at 10:40:03PM +0200, Alex Rønne Petersen wrote:On 29-04-2012 00:04, H. S. Teoh wrote:[...][...]Yeah, .sort is redundant, and besides shouldn't be an array "property" to begin with.Let's not forget .reverse. Why these are properties (and .dup/.idup) is seriously beyond me.....[...] AFAIK, it's a historical accident. These "properties" date from before people decided to distinguish between methods and properties. T -- "A man's wife has more power over him than the state has." -- Ralph Emerson
Apr 29 2012
"deadalnix" <deadalnix gmail.com> wrote in message news:jnhopd$gi3$1 digitalmars.com...- out arguments. We can return tuples, out argument is going backward in history.You can overload on out parameters. You can't overload on return type. So without "out" making an optional output param would be harder to make and uglier to use. That could be even more of a problem if the out param in question is expensive to compute. Also, out is nice when interfacing with C. Returning tuples wouldn't help here. I do agree that maybe we should *prefer* returning tuples over out params (at least once we kill off the useless comma operator and have a concise built-in syntax for tuples), but I don't think tuples are enough to replace out entirely.
Apr 29 2012
Le 29/04/2012 21:30, Nick Sabalausky a écrit :"deadalnix"<deadalnix gmail.com> wrote in message news:jnhopd$gi3$1 digitalmars.com...Good point, but it have many way to work around and shouldn't justify a feature in the core language by itself, especially if, like out parameter, it is a confusing feature.- out arguments. We can return tuples, out argument is going backward in history.You can overload on out parameters. You can't overload on return type. So without "out" making an optional output param would be harder to make and uglier to use. That could be even more of a problem if the out param in question is expensive to compute.Also, out is nice when interfacing with C. Returning tuples wouldn't help here.C don't have out parameters as D have. C have pointer to do kind of out parameters, and D have pointers too, this is a non issue.
Apr 29 2012
On Sun, Apr 29, 2012 at 11:18:12PM +0200, deadalnix wrote: [...]C don't have out parameters as D have. C have pointer to do kind of out parameters, and D have pointers too, this is a non issue.I argue that using 'out' vs. a pointer is a good thing, because it clarifies intent. When you see a pointer, it's far from clear whether it's an input parameter, an output parameter, or both. More and more, I'm leaning towards the opinion that all code should reveal intent, preferably in a language-supported way. Unclear intent is what leads to subtle bugs caused by people calling functions with wrong assumptions. (You'd think this should be a non-problem with programmers, who are presumably smart enough to figure things out without being told in the face, but I've seen too much "enterprise" code by now to not be cynical about it.) T -- Heuristics are bug-ridden by definition. If they didn't have bugs, they'd be algorithms.
Apr 29 2012
On Monday, 30 April 2012 at 02:33:35 UTC, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 11:18:12PM +0200, deadalnix wrote: [...]Of course, a better way would be to change the meaning of the comma operator to allow a Python-style syntax for return values, i.e something like int, Error foo(char[] input, ref Bar){...} auto res, err = foo(input, bar); We would then only allow in and inout parameters. This would be much closer to functional style. There would be no longer any need for the "in" and "out" keywords. If we push a little further, you can also get rid of inout by doing this: int, ref Bar foo(char[] input, ref Bar){...} auto out, bar = foo(input, bar); Every time the compiler sees the same symbol as an input and output parameter, it can assume it's an inout parameter. This, of course, would break a lot of code.C don't have out parameters as D have. C have pointer to do kind of out parameters, and D have pointers too, this is a non issue.I argue that using 'out' vs. a pointer is a good thing, because it clarifies intent. When you see a pointer, it's far from clear whether it's an input parameter, an output parameter, or both. More and more, I'm leaning towards the opinion that all code should reveal intent, preferably in a language-supported way. Unclear intent is what leads to subtle bugs caused by people calling functions with wrong assumptions. (You'd think this should be a non-problem with programmers, who are presumably smart enough to figure things out without being told in the face, but I've seen too much "enterprise" code by now to not be cynical about it.) T
Apr 30 2012
Le 30/04/2012 11:17, SomeDude a écrit :On Monday, 30 April 2012 at 02:33:35 UTC, H. S. Teoh wrote:Exactly.On Sun, Apr 29, 2012 at 11:18:12PM +0200, deadalnix wrote: [...]Of course, a better way would be to change the meaning of the comma operator to allow a Python-style syntax for return values, i.e something like int, Error foo(char[] input, ref Bar){...} auto res, err = foo(input, bar);C don't have out parameters as D have. C have pointer to do kind of out parameters, and D have pointers too, this is a non issue.I argue that using 'out' vs. a pointer is a good thing, because it clarifies intent. When you see a pointer, it's far from clear whether it's an input parameter, an output parameter, or both. More and more, I'm leaning towards the opinion that all code should reveal intent, preferably in a language-supported way. Unclear intent is what leads to subtle bugs caused by people calling functions with wrong assumptions. (You'd think this should be a non-problem with programmers, who are presumably smart enough to figure things out without being told in the face, but I've seen too much "enterprise" code by now to not be cynical about it.) TWe would then only allow in and inout parameters. This would be much closer to functional style. There would be no longer any need for the "in" and "out" keywords. If we push a little further, you can also get rid of inout by doing this: int, ref Bar foo(char[] input, ref Bar){...} auto out, bar = foo(input, bar); Every time the compiler sees the same symbol as an input and output parameter, it can assume it's an inout parameter. This, of course, would break a lot of code.It isn't a good idea.
Apr 30 2012
"SomeDude" <lovelydear mailmetrash.com> wrote in message news:ajdmseliewbindkkoxxj forum.dlang.org...[...]There would be no longer any need for the "in" and "out" keywords.[...]void foo() in{ ... } out{ ... } body{ ... }
Apr 30 2012
On Monday, 30 April 2012 at 18:32:36 UTC, Nick Sabalausky wrote:"SomeDude" <lovelydear mailmetrash.com> wrote in message news:ajdmseliewbindkkoxxj forum.dlang.org...OKay, I meant in the function signatures[...]There would be no longer any need for the "in" and "out" keywords.[...]void foo() in{ ... } out{ ... } body{ ... }
Apr 30 2012
Le 30/04/2012 04:34, H. S. Teoh a écrit :On Sun, Apr 29, 2012 at 11:18:12PM +0200, deadalnix wrote: [...]I do agree. However, I don't think this apply in any way to our case. out parameter is a C usage, and it is confusing in C, because, as you mentioned, you don't know if you pass the pointer because it is an out parameter, because you want to avoid copy, because something else . . . The fact that better constructs (ie Tuples) exists in D make it already clear. And if the point is to fix C, it is useless because the whole thing is already confusing in C.C don't have out parameters as D have. C have pointer to do kind of out parameters, and D have pointers too, this is a non issue.I argue that using 'out' vs. a pointer is a good thing, because it clarifies intent. When you see a pointer, it's far from clear whether it's an input parameter, an output parameter, or both. More and more, I'm leaning towards the opinion that all code should reveal intent, preferably in a language-supported way. Unclear intent is what leads to subtle bugs caused by people calling functions with wrong assumptions. (You'd think this should be a non-problem with programmers, who are presumably smart enough to figure things out without being told in the face, but I've seen too much "enterprise" code by now to not be cynical about it.) T
Apr 30 2012
On Sunday, 29 April 2012 at 19:30:24 UTC, Nick Sabalausky wrote:"deadalnix" <deadalnix gmail.com> wrote in message news:jnhopd$gi3$1 digitalmars.com...Well the functional way would be to use Option types as in: Tuple!(int, Option!ExpensiveType) foobar(bool cond) { if (cond) return tuple(0, newExpensiveType()); else return tuple(-1, Option.None); } I prefer the above as it's more readable IMO (we REALLY should get a much better tuple syntax though ....) I do agree that this won't work when interfacing with C but IMO we shouldn't design D around limitations of C.- out arguments. We can return tuples, out argument is going backward in history.You can overload on out parameters. You can't overload on return type. So without "out" making an optional output param would be harder to make and uglier to use. That could be even more of a problem if the out param in question is expensive to compute. Also, out is nice when interfacing with C. Returning tuples wouldn't help here. I do agree that maybe we should *prefer* returning tuples over out params (at least once we kill off the useless comma operator and have a concise built-in syntax for tuples), but I don't think tuples are enough to replace out entirely.
Apr 30 2012
Le 28/04/2012 20:47, Walter Bright a écrit :Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Ho god D is HUGE ! OK a last one, synchronized on objects. Most of them are not even shared so it is useless, and is is bad separation of concerns between OOP and multithreading. If you want a mutex, declaring it explicitly is the best option.
Apr 28 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?First, I completely agree with some points already made here, and I completely disagree with a few others. A modern compiler should be as powerful and convenient as possible, I completely disagree that a compiler can't do a broad range of things very efficiently _and_ with a smooth learning. Indeed this is what attracted me to D in the first place, the idea that it has the low level power of C++ when you get down to it, but it's also attractive and initially easy to use. What I think should be removed/changed: - Drop is( ... ) and extend "__traits()" (however "__traits" should become .metaof or something along those lines). Also, a easy to understand traits lib should be imported by default like Object.d - Enum as manifest constant - I agree, this is better as "static x = 10" or equivalent. I was actually confused at first when I realized enum's where what was *supposed* to be used for that. - foreach_reverse. Dmitry's gave a good alternative. Though, I think a more intelligent 'foreach' (or even 'for') statement could address this as well. Something like: for (key, value of range, step) { ... } // Where step values which can be deduced at compile time // are used to produce the most optimizated code. - version statements - this would be a lot more consistent as a static if() I think. But it does need a more obvious syntax, possibly something like: static if ("foo" in Compiler.flags) { ... } - .di files - I agree with foobar here. Other language have had this for awhile, and it makes linking a much easier concept. - NaN as default - I've said this before on here, but I think it deserves being said again. FP values defaulting to Nan is a debugging feature, and should be explicitly expressed in areas which need to guarantee a variable is set after declaration. A useful, and consistent default should be used instead. Ints (the other number type) default to zero, and because zero is the most practical and commonly understood, FP values should start here as well. - commas - should be use for tuples and parameters, not as ending marks: int, int foo() { return 5, 6; } auto x, y = 2; // x = 0, y = 2 auto x, y = 2, 3; // x = 2, y = 3 x, y = foo(); // x = 5, y = 6 What should stay: - foreach (or an intelligent 'for' as exampled above). This is an incredibly convenient, tried 'n true feature. - built-in Associative Arrays - one of D's sexiest features. It's very useful for many things, and always having it at your disposal is a logical choice. - properties - another incredibly convenient feature. I think a more sexy implementation of properties are in order, but the construct is great. It would be nice to have properties as a language type, rather than a attribute: struct Foo { property int x { get; private set; } property int y { get() { return x; } set(T t) { x = t; } } } // Or the syntax could follow Types: property x : int { ... } // Which could be templated: property y(T = int) : int { static if (T.isType!int) { ... } else { ... } } - with statement - no reason to kill it really and it's useful in some places. Helps keep code short and readable. - Anonymous class - There's no reason to remove this feature, it's not hurting anyone and it could allow for interesting frameworks similar to jQuery. Other things that would be cool: - static foreach
Apr 28 2012
On 29 April 2012 01:09, F i L <witte2008 gmail.com> wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Hear hear. I completely agree with everything you just said.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?First, I completely agree with some points already made here, and I completely disagree with a few others. A modern compiler should be as powerful and convenient as possible, I completely disagree that a compiler can't do a broad range of things very efficiently _and_ with a smooth learning. Indeed this is what attracted me to D in the first place, the idea that it has the low level power of C++ when you get down to it, but it's also attractive and initially easy to use. What I think should be removed/changed: - Drop is( ... ) and extend "__traits()" (however "__traits" should become .metaof or something along those lines). Also, a easy to understand traits lib should be imported by default like Object.d - Enum as manifest constant - I agree, this is better as "static x = 10" or equivalent. I was actually confused at first when I realized enum's where what was *supposed* to be used for that. - foreach_reverse. Dmitry's gave a good alternative. Though, I think a more intelligent 'foreach' (or even 'for') statement could address this as well. Something like: for (key, value of range, step) { ... } // Where step values which can be deduced at compile time // are used to produce the most optimizated code. - version statements - this would be a lot more consistent as a static if() I think. But it does need a more obvious syntax, possibly something like: static if ("foo" in Compiler.flags) { ... } - .di files - I agree with foobar here. Other language have had this for awhile, and it makes linking a much easier concept. - NaN as default - I've said this before on here, but I think it deserves being said again. FP values defaulting to Nan is a debugging feature, and should be explicitly expressed in areas which need to guarantee a variable is set after declaration. A useful, and consistent default should be used instead. Ints (the other number type) default to zero, and because zero is the most practical and commonly understood, FP values should start here as well. - commas - should be use for tuples and parameters, not as ending marks: int, int foo() { return 5, 6; } auto x, y = 2; // x = 0, y = 2 auto x, y = 2, 3; // x = 2, y = 3 x, y = foo(); // x = 5, y = 6 What should stay: - foreach (or an intelligent 'for' as exampled above). This is an incredibly convenient, tried 'n true feature. - built-in Associative Arrays - one of D's sexiest features. It's very useful for many things, and always having it at your disposal is a logical choice. - properties - another incredibly convenient feature. I think a more sexy implementation of properties are in order, but the construct is great. It would be nice to have properties as a language type, rather than a attribute: struct Foo { property int x { get; private set; } property int y { get() { return x; } set(T t) { x = t; } } } // Or the syntax could follow Types: property x : int { ... } // Which could be templated: property y(T = int) : int { static if (T.isType!int) { ... } else { ... } } - with statement - no reason to kill it really and it's useful in some places. Helps keep code short and readable. - Anonymous class - There's no reason to remove this feature, it's not hurting anyone and it could allow for interesting frameworks similar to jQuery. Other things that would be cool: - static foreach
Apr 28 2012
- properties - another incredibly convenient feature. I think a more sexy implementation of properties are in order, but the construct is great. It would be nice to have properties as a language type, rather than a attribute:To me, properties are much more than a convenience. The important part of it comes from its existence, not its usage. Quite simply, having properties mean that using public member variables does not break encapsulation (as long as having them part of the public interface is intentional). Without properties, you MUST write accessors for all of them on the off chance that you might want to refactor/delegate them in the future. This adds a huge amount of boilerplate code that ends up wasted time 98% of the time. In short, properties existing, even if not used, end up improving both my efficiency and the legibility of my code.
Apr 28 2012
On 2012-04-29 04:32, Francois Chabot wrote:In principle I agree with you. But in practice this doesn't always work. Take this for example: struct Point { int x; int y; } class Widget { Point point; } void main() { auto w = new Widget; writeln(w.point.x); w.point.x++; writeln(w.point.x); } Prints "0" and "1" as expected. If we now change "point" to a property like this: class Widget { //Point point; Point point_; property Point point () { return point_; } property Point point (Point point) { return point_ = point; } } It will now print "0" and "0". This is a silently breaking change. Sure you can change "point" to return by reference: class Widget { Point point_; property ref Point point () { return point_; } property ref Point point (Point point) { writeln("foo"); point_ = point; return point_; } } Which will print "0" and "1" again. But it won't print "foo", meaning you bypassed the getter. To solve this the compiler would need to perform some kind of property rewriting. Translating: w.point.x++; To: auto __p = w.point; __p.x++; w.point = __p; Also you might need to just as well use properties from the beginning because you need virtual properties. It would help if this was allowed: class Widget { property Point point; } Which would translate to: property Point point () { return point_; } property Point point (Point point) { return point_ = point; } -- /Jacob Carlborg- properties - another incredibly convenient feature. I think a more sexy implementation of properties are in order, but the construct is great. It would be nice to have properties as a language type, rather than a attribute:To me, properties are much more than a convenience. The important part of it comes from its existence, not its usage. Quite simply, having properties mean that using public member variables does not break encapsulation (as long as having them part of the public interface is intentional). Without properties, you MUST write accessors for all of them on the off chance that you might want to refactor/delegate them in the future. This adds a huge amount of boilerplate code that ends up wasted time 98% of the time. In short, properties existing, even if not used, end up improving both my efficiency and the legibility of my code.
Apr 29 2012
On 4/29/12, Jacob Carlborg <doob me.com> wrote:In principle I agree with you. But in practice this doesn't always work. Take this for example: Prints "0" and "1" as expected. If we now change "point" to a property like this: It will now print "0" and "0". This is a silently breaking change. Sure you can change "point" to return by reference..This is a great point and an issue I've ran into and talked about before. The compiler really ought to try and convert a call like this: foo.property++; foo.property+=10; into e.g.: foo.property = foo.property.opAdd(1); foo.property = foo.property.opAdd(10); It would make for some really nice APIs if this feature was available. Otherwise I have to resort to template magic and delegate calls such as: class Widget { Notify!Point pos; this() { pos.init(&posSet); } // if pos changes, invoke posChange void posChange(ref Point newPos) { newPos.normalize(); } // e.g. if out of bounds } Unfortunately that template broke in an earlier compiler regression that I haven't noticed until recently (http://d.puremagic.com/issues/show_bug.cgi?id=7991)
Apr 29 2012
On Sun, Apr 29, 2012 at 08:42:23PM +0200, Andrej Mitrovic wrote:On 4/29/12, Jacob Carlborg <doob me.com> wrote:[...] To me, the compiler needs to be fixed so that anytime the return value of a property is used as an lvalue, it should always try to call the setter function, or some kind of setter function, instead of the getter (unless there's no setter, in which case it's OK to call the getter). I chalk this up to a compiler issue, not a language issue. T -- Let X be the set not defined by this sentence...In principle I agree with you. But in practice this doesn't always work. Take this for example: Prints "0" and "1" as expected. If we now change "point" to a property like this: It will now print "0" and "0". This is a silently breaking change. Sure you can change "point" to return by reference..This is a great point and an issue I've ran into and talked about before. The compiler really ought to try and convert a call like this: foo.property++; foo.property+=10; into e.g.: foo.property = foo.property.opAdd(1); foo.property = foo.property.opAdd(10); It would make for some really nice APIs if this feature was available.
Apr 29 2012
On 30-04-2012 04:37, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 08:42:23PM +0200, Andrej Mitrovic wrote:What you just talked about = semantics. So, it is a language issue. -- - AlexOn 4/29/12, Jacob Carlborg<doob me.com> wrote:[...] To me, the compiler needs to be fixed so that anytime the return value of a property is used as an lvalue, it should always try to call the setter function, or some kind of setter function, instead of the getter (unless there's no setter, in which case it's OK to call the getter). I chalk this up to a compiler issue, not a language issue. TIn principle I agree with you. But in practice this doesn't always work. Take this for example: Prints "0" and "1" as expected. If we now change "point" to a property like this: It will now print "0" and "0". This is a silently breaking change. Sure you can change "point" to return by reference..This is a great point and an issue I've ran into and talked about before. The compiler really ought to try and convert a call like this: foo.property++; foo.property+=10; into e.g.: foo.property = foo.property.opAdd(1); foo.property = foo.property.opAdd(10); It would make for some really nice APIs if this feature was available.
Apr 29 2012
"F i L" <witte2008 gmail.com> wrote in message news:oakvbobsvtawtdcasglk forum.dlang.org...Other things that would be cool: - static foreachWe sort of do: // Unrolled at compile-time foreach(T; TypeTuple!(int, string, BigInt)) { ... } I'm not sure that's valid outside a function, though.
Apr 29 2012
Nick Sabalausky:I'm not sure that's valid outside a function, though.It doesn't work outside functions. More info: http://d.puremagic.com/issues/show_bug.cgi?id=4085 Bye, bearophile
Apr 29 2012
On 28 April 2012 21:47, Walter Bright <newshound2 digitalmars.com> wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?I personally find the wealth of features in D to be one of it's major selling points. It helps simplify user code a lot, but I think there is room for some things to be more consistent: * version refuses to allow boolean logic, I need boolean logic, thus version is redundant to me. I find myself using static if almost exclusively in its place. I like the *idea*, but it's un-usably limited. * Consolidation of meta/introspection: __traits(), std.traits, is(), and a few other tricks, I often don't know where I should look to perform a particular introspection task. __traits is unsightly, it looks more like a hack rather than a feature, but it fills perhaps one of the most vital roles in the language. * D has a lot of attributes, many of which I haven't used + don't understand. I suspect many of them could be removed and implemented in the library with a proper user attribute system (which would be really useful to compliment D's introspection anyway). This would also free those keywords when those libraries aren't imported/used. * I don't know the value of AA's in the language, I've only used them once or twice. Because AA's can be implemented in numerous ways (map, hash table, etc), and may be ordered or unordered, the the choice of which to use is actually important to the problem more often than not. As long as the same convenience can be achieved in the library (literal expression?), maybe it should be there.
Apr 28 2012
On 29-04-2012 00:18, Manu wrote:On 28 April 2012 21:47, Walter Bright <newshound2 digitalmars.com <mailto:newshound2 digitalmars.com>> wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? I personally find the wealth of features in D to be one of it's major selling points. It helps simplify user code a lot, but I think there is room for some things to be more consistent: * version refuses to allow boolean logic, I need boolean logic, thus version is redundant to me. I find myself using static if almost exclusively in its place. I like the *idea*, but it's un-usably limited.+1.* Consolidation of meta/introspection: __traits(), std.traits, is(), and a few other tricks, I often don't know where I should look to perform a particular introspection task. __traits is unsightly, it looks more like a hack rather than a feature, but it fills perhaps one of the most vital roles in the language. * D has a lot of attributes, many of which I haven't used + don't understand. I suspect many of them could be removed and implemented in the library with a proper user attribute system (which would be really useful to compliment D's introspection anyway). This would also free those keywords when those libraries aren't imported/used. * I don't know the value of AA's in the language, I've only used them once or twice. Because AA's can be implemented in numerous ways (map, hash table, etc), and may be ordered or unordered, the the choice of which to use is actually important to the problem more often than not. As long as the same convenience can be achieved in the library (literal expression?), maybe it should be there.-- - Alex
Apr 29 2012
On Saturday, April 28, 2012 13:43:27 H. S. Teoh wrote:D has typedef?? Wow. And I thought I had a good grasp of D.It did, but it won't. It's either already been deprecated or will be soon. - Jonathan M Davis
Apr 28 2012
On Saturday, April 28, 2012 11:47:31 Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Well, that's a hard one. There isn't much in the language that I'd remove even if we were doing a complete redesign without caring about backwards compatibility. Most of the stuff that I'd change is already being (or has been) changed. And while D isn't exactly big, it doesn't tend to have dark corners like C++ does. I'm sure that I don't fully grasp everything in D, but it's fairly rare that I run into something that surprises me or that I thought that I understood but don't (though it still does happen sometimes). With C++, it always feels like there's some new detail that pops up that I didn't have a clue about - or that maybe I _did_ know about but had forgotten because of the insane number of little details that C++ has. One _big_ difference between D and C++ as far as complexity goes is that in C++, a _lot_ of the complexity comes from weird things in the language and knowing about how certain things can go horribly wrong (e.g. I can never remember all of the details on how horribly broken multiple inheritence is). It's frequently not an issue of knowing how to do things in the language but rather an issue of knowing what weird side effects an problems happen with certain stuff. With D, on the other hand, the complexity tends to be in just knowing what all of the features are and what they can do. The only feature that comes to mind as probably being overly complex is is expressions, but that complexity can really come in handy sometimes. std.traits should probably do more to alleviate the need for is expressions though so that odds of needing some of the more complicated stuff are lessened. * As for redundant features, the first one that really comes to mind is WYSIWYG string literals. There are what, 4 different types of delimiters for string literals? I don't even remember all of the options. I just always use ` if I don't want any escaping in string literal and " if I do. The others may be valuable enough to have in some contexts, but I _never_ use them. * version vs static if seems kind of redundant, but it isn't really. version is used for a very specific subset of conditional code compilation, and you can define versions on the command line, whereas static if generally checks code properties (like if a type meets certain conditions). So, I think that they should probably be left as is. There would be some value in allowing a list of versions to be given (rather than using logical operators) in order to avoid duplicate code - e.g. version(linux, FreeBSD) {} else version(MacOSX) {} else version(Windows) {} else static assert(0); but that's about the only thing that I'd change with version. And I wouldn't want to get rid of it. * foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro. But we might already be planning to get rid of that. I'm not sure though. * I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call, so I doubt that we could get rid of them without a fair bit of complaining. I think that they're completely redundant and very _un_D. * There seem to be too many ways to do variadic functions. We have to allow C style variadics for extern(C), but having 3 of our own seems like a bit much. Variadic templates are generally all that we need. The others don't seem necessary for the most part. But unfortunately, they should probably be left in so that classes can use them with virtual functions, since they can't use templates. * As for features that add little value, the first one that comes to mind is with. I think that I've used it all of once, and I don't think that I've seen it in other people's code very often. It's hard to grep for (since with is used in comments quite often), but it wouldn't surprise me at all if Phobos doesn't use it at all. Also, I fear that not only does it add little value but that it has a tendency to make code less readable. * Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read. The code is completely backwards. But I appear to be in the minority with that opinion. I also don't like how it creates so many ways to write exactly the same code. It harms readibility. But as much as I dislike many of the applications of UFCS, it _does_ appear to be quite popular. And upon occasion, it may be useful, but I _am_ wishing that we hadn't added it. There are definitely features that I never use (e.g. opDispatch), but for the most part, I think that they're stuff that adds real value for certain types of stuff that I just don't do, so removing them wouldn't really make any sense. Overall, I think that D's feature set is fairly solid. It's mostly just the implementation of said features which is a problem - though some minor tweaks are probably in order (e.g. as Bearophile suggests, make it so that adjacent string literals don't concatenate). - Jonathan M Davis
Apr 28 2012
Jonathan M Davis:* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call,For single structs I prefer D-style initialization. But take a look at this code, if you replace those C-style initializers with D-style, even using aliases to shorten the code to single letters, that data section becomes more noisy: http://rosettacode.org/wiki/Ray-casting_algorithm#D* As for features that add little value, the first one that comes to mind is with. I think that I've used it all of once, and I don't think that I've seen it in other people's code very often.It's rather common in Pascal/Delphi programming. I use it now and then. For a case where it's very handy see here, with an enumeration: http://rosettacode.org/wiki/Stable_marriage_problem#Alternative_versionIt's hard to grep for (since with is used in comments quite often),Try to search for "with(" or "with\s(", that are less common in normal text.* Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read.For me it makes that kind of code way simpler to read...The code is completely backwards.It means call d on 5, then call c on the result, then call b on the result, and then call a on the result. It's better than before :-) Bye, bearophile
Apr 28 2012
On Sunday, 29 April 2012 at 01:06:54 UTC, bearophile wrote:I have one source file called staticdata.d; Here immutable global data is stored. It's literally pages and pages of data and i only using static this() when building an AA. //excerpt: /NP and VT aliases. immutable SubRecordParts subParts[] = [ {"AADT", "", 16, [ //alchemy (apparatus) NP(VT.ranged_32, "Apparatus"), NP(VT.float_32, "Quality"), NP(VT.float_32, "Weight"), NP(VT.i_32, "uses")]}, {"AODT", "", 24, [ //armor NP(VT.ranged_32, "Armor Body Type"), NP(VT.float_32, "Weight"), NP(VT.i_32, "Value"), NP(VT.i_32, "Health"), NP(VT.i_32, "Enchant Points"), NP(VT.i_32, "Armour")]}, {"BKDT", "", 20, [ //book NP(VT.float_32, "Weight"), NP(VT.i_32, "Value"), NP(VT.i_32, "isScroll"), NP(VT.ranged_32, "Skill ID"), NP(VT.i_32, "Enchantment points")]}]; Would you really force me to use fully named and qualified for every element? More verbose but helps not at all. immutable SubRecordParts subParts[] = [ SubRecordParts("AADT", "", 16, [ //alchemy (apparatus) NotePart(ValueType.ranged_32, "Apparatus"), NotePart(ValueType.float_32, "Quality"), NotePart(ValueType.float_32, "Weight"), NotePart(ValueType.i_32, "uses")]), SubRecordParts("AODT", "", 24, [ //armor NotePart(ValueType.ranged_32, "Armor Body Type"), NotePart(ValueType.float_32, "Weight"), NotePart(ValueType.i_32, "Value"), NotePart(ValueType.i_32, "Health"), NotePart(ValueType.i_32, "Enchant Points"), NotePart(ValueType.i_32, "Armour")]), SubRecordParts("BKDT", "", 20, [ //book NotePart(ValueType.float_32, "Weight"), NotePart(ValueType.i_32, "Value"), NotePart(ValueType.i_32, "isScroll"), NotePart(ValueType.ranged_32, "Skill ID"), NotePart(ValueType.i_32, "Enchantment points")]) ];* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call,For single structs I prefer D-style initialization. But take a look at this code, if you replace those C-style initializers with D-style, even using aliases to shorten the code to single letters, that data section becomes more noisy: http://rosettacode.org/wiki/Ray-casting_algorithm#D
Apr 28 2012
On Sunday, April 29, 2012 03:06:53 bearophile wrote:I know that you find easier to read. A number of people do. But it is just so backwards in comparison to how stuff normally works, that it hurts my brain. But I've done enough functional programming that I find something likea(b(c(d(5)))) to be completely straightforward, and for some reason not everyone does. And while I _never_ intend to use UFCS in this manner, I'm going to forever have to read the code of others who do, which I find to be a major negative. But regardless of my personal opinion on the matter, it's clear that enough people like UFCS that it's not going anywhere unless something seriously wrong is found with it which makes it untenable. - Jonathan M Davis* Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read.For me it makes that kind of code way simpler to read...The code is completely backwards.It means call d on 5, then call c on the result, then call b on the result, and then call a on the result. It's better than before :-)
Apr 28 2012
On 29-04-2012 03:40, Jonathan M Davis wrote:On Sunday, April 29, 2012 03:06:53 bearophile wrote:like |> and <|.I know that you find easier to read. A number of people do. But it is just so backwards in comparison to how stuff normally works, that it hurts my brain. But I've done enough functional programming that I find something likea(b(c(d(5)))) to be completely straightforward, and for some reason not everyone does. And while I _never_ intend to use UFCS in this manner, I'm going to forever have to read the code of others who do, which I find to be a major negative.* Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read.For me it makes that kind of code way simpler to read...The code is completely backwards.It means call d on 5, then call c on the result, then call b on the result, and then call a on the result. It's better than before :-)But regardless of my personal opinion on the matter, it's clear that enough people like UFCS that it's not going anywhere unless something seriously wrong is found with it which makes it untenable. - Jonathan M Davis-- - Alex
Apr 29 2012
On 29.04.2012 5:06, bearophile wrote:Jonathan M Davis:bleh C++ doesn't have reverse loop in the language. all there is rbegin() and rend(). And this attitude reminds me of the old STL days. What's wrong with you people? Am I back to 90s ?* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient.Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...Doesn't have to do anything with the LANGUAGE. Yesterday I tried GDC. Damn I didn't regret it :)Such code (tables) is usually generated anyway. [snip reasonable parts ;)] -- Dmitry Olshansky* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call,For single structs I prefer D-style initialization. But take a look at this code, if you replace those C-style initializers with D-style, even using aliases to shorten the code to single letters, that data section becomes more noisy: http://rosettacode.org/wiki/Ray-casting_algorithm#D
Apr 28 2012
On Sun, Apr 29, 2012 at 10:03:43AM +0400, Dmitry Olshansky wrote:On 29.04.2012 5:06, bearophile wrote:[...][...] Unfortunately, even GDC doesn't inline opApply and its delegate for the simplest of loops: struct S { int data[]; int opApply(int delegate(ref int) dg) { foreach (d; data) { if (auto r = dg(d)) return r; } return 0; } } void main() { S s; foreach (e; s) { writeln(e); } } I think it's because the front-end always generates the full delegate passing code without inlining anything. IMO, this case *need* to be aggressively inlined in order to make D's generic programming capabilities a stronger selling point. T -- "Computer Science is no more about computers than astronomy is about telescopes." -- E.W. DijkstraLoops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...Doesn't have to do anything with the LANGUAGE. Yesterday I tried GDC. Damn I didn't regret it :)
Apr 29 2012
Le 30/04/2012 04:52, H. S. Teoh a écrit :On Sun, Apr 29, 2012 at 10:03:43AM +0400, Dmitry Olshansky wrote:It is an implementation issue (a real and serious one, but still). It should be fixed by implementation, not language design.On 29.04.2012 5:06, bearophile wrote:[...][...] Unfortunately, even GDC doesn't inline opApply and its delegate for the simplest of loops: struct S { int data[]; int opApply(int delegate(ref int) dg) { foreach (d; data) { if (auto r = dg(d)) return r; } return 0; } } void main() { S s; foreach (e; s) { writeln(e); } } I think it's because the front-end always generates the full delegate passing code without inlining anything. IMO, this case *need* to be aggressively inlined in order to make D's generic programming capabilities a stronger selling point. TLoops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...Doesn't have to do anything with the LANGUAGE. Yesterday I tried GDC. Damn I didn't regret it :)
Apr 30 2012
On Sunday, 29 April 2012 at 01:06:54 UTC, bearophile wrote:retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...Slightly related: For this: --- import core.stdc.stdio; import std.algorithm; import std.range; void main() { int sum; foreach (i; retro(iota(11))) sum += i; printf("%d\n", sum); } --- LDC produces --- __Dmain: pushq %rax movl $0x00000037,%esi xorb %al,%al callq _printf xorl %esi,%esi movl %eax,0x04(%rsp) movl %esi,%eax popq %rdx ret --- Now that's constant folding… ;) David
Apr 29 2012
On 29-04-2012 03:06, bearophile wrote:Jonathan M Davis:Completely agree.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call,For single structs I prefer D-style initialization. But take a look at this code, if you replace those C-style initializers with D-style, even using aliases to shorten the code to single letters, that data section becomes more noisy: http://rosettacode.org/wiki/Ray-casting_algorithm#D* As for features that add little value, the first one that comes to mind is with. I think that I've used it all of once, and I don't think that I've seen it in other people's code very often.It's rather common in Pascal/Delphi programming. I use it now and then. For a case where it's very handy see here, with an enumeration: http://rosettacode.org/wiki/Stable_marriage_problem#Alternative_versionIt's hard to grep for (since with is used in comments quite often),Try to search for "with(" or "with\s(", that are less common in normal text.* Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read.For me it makes that kind of code way simpler to read...Amen.The code is completely backwards.It means call d on 5, then call c on the result, then call b on the result, and then call a on the result. It's better than before :-)Bye, bearophile-- - Alex
Apr 29 2012
Le 29/04/2012 03:06, bearophile a écrit :Jonathan M Davis:This is an implementation issue and shouldn't be an argument for language design.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 29 2012
On Sunday, 29 April 2012 at 21:18:40 UTC, deadalnix wrote:Le 29/04/2012 03:06, bearophile a écrit :The 'sufficiently smart compiler' argument is old and invalid. Please do not use it.Jonathan M Davis:This is an implementation issue and shouldn't be an argument for language design.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 29 2012
On 29-04-2012 23:54, Peter Alexander wrote:On Sunday, 29 April 2012 at 21:18:40 UTC, deadalnix wrote:Indeed; at some point, you have to admit that implementation will have some impact on design. We don't live an ideal world, unfortunately. ;) -- - AlexLe 29/04/2012 03:06, bearophile a écrit :The 'sufficiently smart compiler' argument is old and invalid. Please do not use it.Jonathan M Davis:This is an implementation issue and shouldn't be an argument for language design.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 29 2012
On 30.04.2012 1:54, Peter Alexander wrote:On Sunday, 29 April 2012 at 21:18:40 UTC, deadalnix wrote:Right, nowdays any compiler is either smart enough or a dead meat that nobody uses. P.S. dmd is kind of work in progress ;) -- Dmitry OlshanskyLe 29/04/2012 03:06, bearophile a écrit :The 'sufficiently smart compiler' argument is old and invalid. Please do not use it.Jonathan M Davis:This is an implementation issue and shouldn't be an argument for language design.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 30 2012
On Monday, 30 April 2012 at 07:37:13 UTC, Dmitry Olshansky wrote:A smart enough compiler would understand natural language and turn it into efficient assembly. :o)Right, nowdays any compiler is either smart enough or a dead meat that nobody uses. P.S. dmd is kind of work in progress ;)
Apr 30 2012
On 30.04.2012 13:21, SomeDude wrote:On Monday, 30 April 2012 at 07:37:13 UTC, Dmitry Olshansky wrote:Yeah, unless it decides to take a vacation. :) Or you know such a compiler may have a lot of more interesting things to do so our mundane ideas may just have to wait for a while. -- Dmitry OlshanskyA smart enough compiler would understand natural language and turn it into efficient assembly. :o)Right, nowdays any compiler is either smart enough or a dead meat that nobody uses. P.S. dmd is kind of work in progress ;)
Apr 30 2012
Le 29/04/2012 23:54, Peter Alexander a écrit :On Sunday, 29 April 2012 at 21:18:40 UTC, deadalnix wrote:This is a case by case issue. You should consider fixing implementation issue with implementation, and consider language design if that first one fail. If you don't think this is right, the only rational solution you have is to use assembly directly. As you fail to show how this is something that isn't reasonably implementable, you have no argument.Le 29/04/2012 03:06, bearophile a écrit :The 'sufficiently smart compiler' argument is old and invalid. Please do not use it.Jonathan M Davis:This is an implementation issue and shouldn't be an argument for language design.* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 30 2012
On Sun, Apr 29, 2012 at 03:06:53AM +0200, bearophile wrote:Jonathan M Davis:[...] IMO, the compiler needs to _aggressively_ inline opApply() delegates, unless it's impossible (e.g. opApply is recursive), or perhaps exceeds some reasonable size limit for loop inlining). It's rather disheartening to design a great abstract type for manipulating collections, only to have opApply always incur the overhead of allocating and invoking a delegate _every loop iteration_, even when opApply is as simple as: int opApply(int delegate(ref T arg) dg) { someSetupCode(); for (i=0; i<n; i++) { dg(element[i]); } someCleanupCode(); } As far as I'm concerned, the compiler *should* just inline the whole thing (both opApply and the delegate body) when you write foreach(c; container) {...}. There's no reason for such a trivial loop to incur a call to a delegate every iteration. Powerful abstractions such as opApply need to be optimized to the max, so that D's generic programming capabilities can be a strong selling point. T -- Nearly all men can stand adversity, but if you want to test a man's character, give him power. -- Abraham Lincoln* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...
Apr 29 2012
On 04/30/2012 04:47 AM, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 03:06:53AM +0200, bearophile wrote:Use a scope delegate in the opApply signature to avoid the allocation.Jonathan M Davis:[...] IMO, the compiler needs to _aggressively_ inline opApply() delegates, unless it's impossible (e.g. opApply is recursive), or perhaps exceeds some reasonable size limit for loop inlining). It's rather disheartening to design a great abstract type for manipulating collections, only to have opApply always incur the overhead of allocating* foreach_reverse is essentially redudant at this point (not to mention confusing if combined with delegates), since we have retro.retro() can't replace foreach_reverse until the front-end demonstrability produces asm code equally efficient. Loops _must_ be fully efficient, they are a basic language construct, this is very important. Even foreach() is sometimes not equally efficient as a for() in some cases...and invoking a delegate _every loop iteration_, even when opApply is as simple as: int opApply(int delegate(ref T arg) dg) { someSetupCode(); for (i=0; i<n; i++) { dg(element[i]); } someCleanupCode(); } As far as I'm concerned, the compiler *should* just inline the whole thing (both opApply and the delegate body) when you write foreach(c; container) {...}. There's no reason for such a trivial loop to incur a call to a delegate every iteration. Powerful abstractions such as opApply need to be optimized to the max, so that D's generic programming capabilities can be a strong selling point. T
Apr 30 2012
There is no tool (maybe the compiler could provide such a tool) to remove all comments? That way, you could do: cat file.d | tool | grep whateverIt's hard to grep for (since with is used in comments quite often),Try to search for "with(" or "with\s(", that are less common in normal text.
May 03 2012
Le 28/04/2012 20:47, Walter Bright a écrit :What's your list?- builtin complex types (I don't _need_ be able to write "4 + 5i") - builtin associative arrays - some builtin properties like arr.sort - lazy, I use it only for logging - foreach_reverse, never used it - comma operator: when do you ever need it? - in operator Other than that, as a user I can't say having a lot of features is a big problem, it's a major selling point.
Apr 28 2012
On 29-04-2012 03:20, ponce wrote:Le 28/04/2012 20:47, Walter Bright a écrit :+1.What's your list?- builtin complex types (I don't _need_ be able to write "4 + 5i")- builtin associative arrays - some builtin properties like arr.sort+1, and .reverse. I'm also against .dup and .idup being properties, but these don't modify the array in place, so I take less issue with them.- lazy, I use it only for logginglazy is horribly broken in many ways. Try to make a lazy value where the producing delegate is pure. (Hint: You can't.)- foreach_reverse, never used it - comma operator: when do you ever need it?I've never used it intentionally, ever, but have been bitten in the ass countless times because of it.- in operatorDisagree. However, I do think it needs to made more useful (for instance, I simply don't understand why I can't use in to test for existence in an array).Other than that, as a user I can't say having a lot of features is a big problem, it's a major selling point.-- - Alex
Apr 29 2012
Alex Rønne Petersen:Sometimes I use std.exception.enforce(), that uses lazy. Bye, bearophile- lazy, I use it only for logginglazy is horribly broken in many ways.<
Apr 29 2012
On Sunday, 29 April 2012 at 20:50:02 UTC, Alex Rønne Petersen wrote:Complexity of the operation. in on an array is not nearly the same as with an associative array.- in operatorDisagree. However, I do think it needs to made more useful (for instance, I simply don't understand why I can't use in to test for existence in an array).
Apr 30 2012
On 01-05-2012 03:41, Jesse Phillips wrote:On Sunday, 29 April 2012 at 20:50:02 UTC, Alex Rønne Petersen wrote:I know, but it's very intuitive still; see Python. -- - AlexComplexity of the operation. in on an array is not nearly the same as with an associative array.- in operatorDisagree. However, I do think it needs to made more useful (for instance, I simply don't understand why I can't use in to test for existence in an array).
Apr 30 2012
On Tuesday, 1 May 2012 at 02:26:53 UTC, Alex Rønne Petersen wrote:On 01-05-2012 03:41, Jesse Phillips wrote:And that's why it's somewhat dangerous. Because it's so easy to use, someone that doesn't pay enough attention may overlook the fact that he is not using the right data structure. If he often has to do that more than once, he is using the wrong tool for the job. I agree it would be syntaxically nice, but I worry giving this syntactic sugar for what's a for loop with lots of comparisons isn't such a good idea. And the comparisons themselves are subject to caution. If for instance it's an array of floats, or some custom objects, it's very unlikely that you are going to compare bit by bit. So basically, this would be useful only for integers and chars.Complexity of the operation. in on an array is not nearly the same as with an associative array.I know, but it's very intuitive still; see Python.
Apr 30 2012
On 01-05-2012 06:44, SomeDude wrote:On Tuesday, 1 May 2012 at 02:26:53 UTC, Alex Rønne Petersen wrote:1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language? 2) The same holds true for AAs keyed by floats. -- - AlexOn 01-05-2012 03:41, Jesse Phillips wrote:And that's why it's somewhat dangerous. Because it's so easy to use, someone that doesn't pay enough attention may overlook the fact that he is not using the right data structure. If he often has to do that more than once, he is using the wrong tool for the job. I agree it would be syntaxically nice, but I worry giving this syntactic sugar for what's a for loop with lots of comparisons isn't such a good idea. And the comparisons themselves are subject to caution. If for instance it's an array of floats, or some custom objects, it's very unlikely that you are going to compare bit by bit. So basically, this would be useful only for integers and chars.Complexity of the operation. in on an array is not nearly the same as with an associative array.I know, but it's very intuitive still; see Python.
May 01 2012
On Tuesday, 1 May 2012 at 14:31:25 UTC, Alex Rønne Petersen wrote:1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?It's not crippling the language. Nothing prevents you from writing a loop. Or using a library find function that does the same thing. But the name "find" gives you a hint that it's not magical and that it has a cost, while with "if( foo in bar)", it is too easy to forget that we are actually potentially performing an O(n) operation. In an AA, the 'in' keyword performs a O(1) operation, so that's ok to use it as a syntactic sugar.
May 01 2012
On 01-05-2012 16:41, SomeDude wrote:On Tuesday, 1 May 2012 at 14:31:25 UTC, Alex Rønne Petersen wrote:No, it is not an O(1) operation, it is *close* to O(1) (as much sense as that statement can make). I don't know why you associate any particular complexity with 'in' in the first place. And I do think we're crippling the language, considering Python (and probably other languages) has had this feature since forever. I'm seriously worried. It seems to me like we're trying to cater to people who can't reason about the types in their program and the complexities of performing various operations on them. Since when did algorithmic complexity become a reason to take away syntax sugar? -- - Alex1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?It's not crippling the language. Nothing prevents you from writing a loop. Or using a library find function that does the same thing. But the name "find" gives you a hint that it's not magical and that it has a cost, while with "if( foo in bar)", it is too easy to forget that we are actually potentially performing an O(n) operation. In an AA, the 'in' keyword performs a O(1) operation, so that's ok to use it as a syntactic sugar.
May 01 2012
No, it is not an O(1) operation, it is *close* to O(1) (as much sense as that statement can make). I don't know why you associate any particular complexity with 'in' in the first place. And I do think we're crippling the language, considering Python (and probably other languages) has had this feature since forever. I'm seriously worried. It seems to me like we're trying to cater to people who can't reason about the types in their program and the complexities of performing various operations on them. Since when did algorithmic complexity become a reason to take away syntax sugar?+1 I do argee. opIn is handy for arrays, too. That the complexity would be linear and thus it should be disallowed is not a valid argument in my opinion, because with the exact same argument you could kick std.algorithm.find out of phobos. It is just obvious to every trained programmer that finding an element in an unordered list takes O(n).
May 02 2012
On 5/2/12 6:15 AM, Tobias Pankrath wrote:The problem here is making complexity an implementation detail of a uniform interface (e.g. over hashes and linear containers). That is fail. AndreiNo, it is not an O(1) operation, it is *close* to O(1) (as much sense as that statement can make). I don't know why you associate any particular complexity with 'in' in the first place. And I do think we're crippling the language, considering Python (and probably other languages) has had this feature since forever. I'm seriously worried. It seems to me like we're trying to cater to people who can't reason about the types in their program and the complexities of performing various operations on them. Since when did algorithmic complexity become a reason to take away syntax sugar?+1 I do argee. opIn is handy for arrays, too. That the complexity would be linear and thus it should be disallowed is not a valid argument in my opinion, because with the exact same argument you could kick std.algorithm.find out of phobos. It is just obvious to every trained programmer that finding an element in an unordered list takes O(n).
May 02 2012
On 05/02/2012 04:01 PM, Andrei Alexandrescu wrote:On 5/2/12 6:15 AM, Tobias Pankrath wrote:The interface is different: void main(){ int[] a = [0,0,0]; a[2] = 3; assert(2 !in a); } vs. void main(){ int[int] aa; aa[2] = 3; assert(2 in aa); }The problem here is making complexity an implementation detail of a uniform interface (e.g. over hashes and linear containers). That is fail. AndreiNo, it is not an O(1) operation, it is *close* to O(1) (as much sense as that statement can make). I don't know why you associate any particular complexity with 'in' in the first place. And I do think we're crippling the language, considering Python (and probably other languages) has had this feature since forever. I'm seriously worried. It seems to me like we're trying to cater to people who can't reason about the types in their program and the complexities of performing various operations on them. Since when did algorithmic complexity become a reason to take away syntax sugar?+1 I do argee. opIn is handy for arrays, too. That the complexity would be linear and thus it should be disallowed is not a valid argument in my opinion, because with the exact same argument you could kick std.algorithm.find out of phobos. It is just obvious to every trained programmer that finding an element in an unordered list takes O(n).
May 02 2012
On 5/2/12 10:20 AM, Timon Gehr wrote:The interface is different: void main(){ int[] a = [0,0,0]; a[2] = 3; assert(2 !in a); } vs. void main(){ int[int] aa; aa[2] = 3; assert(2 in aa); }The syntactic interface is the same. That would be the semantic interface, which makes the idea twice as bad. Andrei
May 02 2012
On 05/02/2012 05:25 PM, Andrei Alexandrescu wrote:On 5/2/12 10:20 AM, Timon Gehr wrote:Encapsulation of complexity is a problem if it is not obvious to the programmer. I am not sure it can even be called such if the semantics is different.The interface is different: void main(){ int[] a = [0,0,0]; a[2] = 3; assert(2 !in a); } vs. void main(){ int[int] aa; aa[2] = 3; assert(2 in aa); }The syntactic interface is the same.That would be the semantic interface, which makes the idea twice as bad. AndreiI tend to agree, but I think that the two points are mutually exclusive.
May 02 2012
On Tuesday, 1 May 2012 at 14:41:43 UTC, SomeDude wrote:On Tuesday, 1 May 2012 at 14:31:25 UTC, Alex Rønne Petersen wrote:I remember this was the argument Andrei also came up. Still can't make any sense out of it. If someone have some detailed reference please share! If you have it just for a niche usage, why do you have it at all? With UFCS "bar.contains(foo)" precise enough. You can make same argument for every operator in any language if you have operator overloading. And it would be against operator overloading, not particularly "in". -- Didn't know "http://forum.dlang.org/" adopted that unreadable/annoying to no end captchas.1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?It's not crippling the language. Nothing prevents you from writing a loop. Or using a library find function that does the same thing. But the name "find" gives you a hint that it's not magical and that it has a cost, while with "if( foo in bar)", it is too easy to forget that we are actually potentially performing an O(n) operation. In an AA, the 'in' keyword performs a O(1) operation, so that's ok to use it as a syntactic sugar.
May 01 2012
On Tuesday, May 01, 2012 16:31:25 Alex Rønne Petersen wrote:1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?If in is not restricted to a particular level Big-O complexity, then you cannot safely use it in generic code. That's why all of the functions in std.container give their Big-O complexity. In C++ [] is supposed to be O(log n) at worst. I would expect it to be the same in D, and since in is doing essentially the same operation, I would expect it to have the same Big-O complexity. No, nothing is stopping a programmer from giving it horrible complexity, but the standard library and language should _definitely_ stick to O(log n) worst case for in and []. It would be a disaster for generic algorithms if in worked on normal arrays, because it would not be possible to maintain the required Big-O complexity. - Jonathan M Davis
May 01 2012
On 01-05-2012 19:09, Jonathan M Davis wrote:On Tuesday, May 01, 2012 16:31:25 Alex Rønne Petersen wrote:I don't think 'in' is actually used in any generic code (other than code specifically written for AAs, in which it *does* have a specific complexity in any case). I know I wouldn't use 'in' in truly generic code in any case, exactly because it has no defined complexity (even today; it's overloadable just like most other binary operators).1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?If in is not restricted to a particular level Big-O complexity, then you cannot safely use it in generic code. That's why all of the functions in std.container give their Big-O complexity.In C++ [] is supposed to be O(log n) at worst. I would expect it to be the same in D, and since in is doing essentially the same operation, I would expect it to have the same Big-O complexity.This is a good point, but not one I would subscribe to; it only holds true if you consider 'in' to be an operation purely limited to AAs. But this is already not the case given that it can be overloaded. So, I don't think that it having different complexity for arrays is a big deal. Personally, I consider 'in' to be syntax sugar for the language user. To me, it does not seem like a feature that a library of generic algorithms should be using at all.No, nothing is stopping a programmer from giving it horrible complexity, but the standard library and language should _definitely_ stick to O(log n) worst case for in and []. It would be a disaster for generic algorithms if in worked on normal arrays, because it would not be possible to maintain the required Big-O complexity.I agree that any overload of [] and 'in' that Phobos does should stick to that constraint when possible (I say when possible, because sometimes innovative uses of these operators can't stick to this rather strict and mundane constraint; consider for example interaction with a database or what do I know...). But again, I don't think 'in' is something a generic algorithm should be using. We have the functions in std.algorithm and std.container if we need to write generic code. Also, I don't think language design should be *too* biased by the standard library's preferences. Not everyone agrees with Phobos conventions and we have to respect that IMHO. Just because it's a standard library doesn't mean that it should dictate users of the language who don't use the standard library.- Jonathan M Davis-- - Alex
May 01 2012
On Tuesday, 1 May 2012 at 17:50:38 UTC, Alex Rønne Petersen wrote:On 01-05-2012 19:09, Jonathan M Davis wrote:vote++ I like your POV that operators are useful shortcuts (syntax sugar) meant for the end user whereas library authors should use the full function names for generic code. IIRC C++'s STL does the same - for instance the map::operator[] is a simple wrapper around map's functions. Is this included in D's style guide?On Tuesday, May 01, 2012 16:31:25 Alex Rønne Petersen wrote:I don't think 'in' is actually used in any generic code (other than code specifically written for AAs, in which it *does* have a specific complexity in any case). I know I wouldn't use 'in' in truly generic code in any case, exactly because it has no defined complexity (even today; it's overloadable just like most other binary operators).1) So because some people might use a feature incorrectly due to lack of knowledge in algorithms and data structures, we should cripple the language?If in is not restricted to a particular level Big-O complexity, then you cannot safely use it in generic code. That's why all of the functions in std.container give their Big-O complexity.In C++ [] is supposed to be O(log n) at worst. I would expect it to be the same in D, and since in is doing essentially the same operation, I would expect it to have the same Big-O complexity.This is a good point, but not one I would subscribe to; it only holds true if you consider 'in' to be an operation purely limited to AAs. But this is already not the case given that it can be overloaded. So, I don't think that it having different complexity for arrays is a big deal. Personally, I consider 'in' to be syntax sugar for the language user. To me, it does not seem like a feature that a library of generic algorithms should be using at all.No, nothing is stopping a programmer from giving it horrible complexity, but the standard library and language should _definitely_ stick to O(log n) worst case for in and []. It would be a disaster for generic algorithms if in worked on normal arrays, because it would not be possible to maintain the required Big-O complexity.I agree that any overload of [] and 'in' that Phobos does should stick to that constraint when possible (I say when possible, because sometimes innovative uses of these operators can't stick to this rather strict and mundane constraint; consider for example interaction with a database or what do I know...). But again, I don't think 'in' is something a generic algorithm should be using. We have the functions in std.algorithm and std.container if we need to write generic code. Also, I don't think language design should be *too* biased by the standard library's preferences. Not everyone agrees with Phobos conventions and we have to respect that IMHO. Just because it's a standard library doesn't mean that it should dictate users of the language who don't use the standard library.- Jonathan M Davis
May 01 2012
On Tuesday, 1 May 2012 at 21:03:35 UTC, foobar wrote:vote++ I like your POV that operators are useful shortcuts (syntax sugar) meant for the end user whereas library authors should use the full function names for generic code. IIRC C++'s STL does the same - for instance the map::operator[] is a simple wrapper around map's functions. Is this included in D's style guide?vote------------- If something is a bad idea for a library, I don't see why it could be a good idea for the user code. After all, the standard library IS user code. The fact that it's in a library or not doesn't change anything to the fact that your syntactic sugar is hiding a potential problem.
May 01 2012
On Sat, Apr 28, 2012 at 04:56:52PM -0700, Jonathan M Davis wrote: [...]One _big_ difference between D and C++ as far as complexity goes is that in C++, a _lot_ of the complexity comes from weird things in the language and knowing about how certain things can go horribly wrong (e.g. I can never remember all of the details on how horribly broken multiple inheritence is).Ugh. C++ multiple inheritance is a labyrinth, nay, a veritable minefield of subtle tripwires, inconvenient limitations, and a source of hair-tearing headaches. It's one of the bigger problems with C++'s OO implementation. Java's idea of single inheritance, multiple interfaces is a much better concept.It's frequently not an issue of knowing how to do things in the language but rather an issue of knowing what weird side effects an problems happen with certain stuff. With D, on the other hand, the complexity tends to be in just knowing what all of the features are and what they can do.Except is() expressions, which appear to be totally arbitrary to me. As far as I'm concerned, it's just "memorize these bunch of arbitrary special rules".The only feature that comes to mind as probably being overly complex is is expressions, but that complexity can really come in handy sometimes. std.traits should probably do more to alleviate the need for is expressions though so that odds of needing some of the more complicated stuff are lessened.Needing to rely on std.traits is backwards, IMO. It's the compiler that knows all this stuff about types, why should we need to consult a library to get at the information? But anyway, the *functionality* of is-expressions are very useful, and, I'd argue, necessary. It's just that the syntax is atrocious and needs fixing.* As for redundant features, the first one that really comes to mind is WYSIWYG string literals. There are what, 4 different types of delimiters for string literals?Only 4? I thought there were more. Last I looked, there were like 6 separate cases.I don't even remember all of the options. I just always use ` if I don't want any escaping in string literal and " if I do. The others may be valuable enough to have in some contexts, but I _never_ use them.Yeah, I agree we should merge some of the string literal syntaxes. Some of them are useful (I'm a sucker for heredoc syntax) but currently it seems like just way too many options for something that should be really straightforward. [...]* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call, so I doubt that we could get rid of them without a fair bit of complaining. I think that they're completely redundant and very _un_D.It's annoying to have to write a constructor whose only purpose is to copy arguments into field members. Many uses of structs don't need the encapsulation that ctors were intended for.* There seem to be too many ways to do variadic functions. We have to allow C style variadics for extern(C), but having 3 of our own seems like a bit much. Variadic templates are generally all that we need. The others don't seem necessary for the most part. But unfortunately, they should probably be left in so that classes can use them with virtual functions, since they can't use templates.IMO we should unify variadic syntax into one (or perhaps leave the C variadics separate, since they're just for compatibility with C), and let the compiler implement each appropriately for the given context. [...]* Increasingly, I don't like UFCS. I think that in most cases, it complicates code for little value. And I _really_ don't like how it results in people flipping chains of a(b(c(d(5)))) calls into something like d(5).c().b.().a(). I think that it makes the code way harder to read. The code is completely backwards. But I appear to be in the minority with that opinion. I also don't like how it creates so many ways to write exactly the same code. It harms readibility. But as much as I dislike many of the applications of UFCS, it _does_ appear to be quite popular. And upon occasion, it may be useful, but I _am_ wishing that we hadn't added it.Strange, I like it a lot because unifying function calls makes it very easy to write generic code without sprinkling static ifs everywhere. [...]Overall, I think that D's feature set is fairly solid. It's mostly just the implementation of said features which is a problem - though some minor tweaks are probably in order (e.g. as Bearophile suggests, make it so that adjacent string literals don't concatenate).[...] I thought adjacent string lits have been deprecated or no longer supported? Personally I like it; it lets you format long literals over multiple lines without needing a ~ in between. And also, recently I found this annoyance: throw new Exception("A very long message (%s) that is "~ "broken across multiple (%d) lines".format(msg,count)); This doesn't work because ~ has lower precedence than ., so you need extra parentheses around the strings: throw new Exception(("A very long message (%s) that is "~ "broken across multiple (%d) lines").format(msg,count)); Whereas being able to concatenate adjacent literals would've been this a lot more readable. T -- I don't trust computers, I've spent too long programming to think that they can get anything right. -- James Miller
Apr 28 2012
H. S. Teoh:It's annoying to have to write a constructor whose only purpose is to copy arguments into field members.This is not needed in D for structs. Try it.I thought adjacent string lits have been deprecated or no longer supported?Walter accepted to deprecate it lot of time ago, but it's not implemented yet.Personally I like it; it lets you format long literals over multiple lines without needing a ~ in between.If you write an array literal with many strings inside, and you forget a comma, you get less strings, silently. This is a sourceAnd also, recently I found this annoyance:Right, the precedence of the ~ operator different from the precedence of the invisible space operator. This causes some disadvantages. But I think the advantages in gained correctness are more important. Bye, bearophile
Apr 28 2012
On Saturday, April 28, 2012 18:24:20 H. S. Teoh wrote:You don't have to. If you have struct S { int field1; float field2; string field3; } then you can do auto s = S(5, 7.2, "hello"); The ability to do S s = {5, 7.2, "hello"}; gains you _nothing_. - Jonathan M Davis* I hate C style struct initializers and would really like to see them go, but for reasons that I don't understand, people actually use them rather than using a proper constructor call, so I doubt that we could get rid of them without a fair bit of complaining. I think that they're completely redundant and very _un_D.It's annoying to have to write a constructor whose only purpose is to copy arguments into field members. Many uses of structs don't need the encapsulation that ctors were intended for.
Apr 28 2012
On Sunday, 29 April 2012 at 01:36:10 UTC, Jonathan M Davis wrote:On Saturday, April 28, 2012 18:24:20 H. S. Teoh wrote: then you can do auto s = S(5, 7.2, "hello"); The ability to do S s = {5, 7.2, "hello"}; gains you _nothing_.Depends on how many levels you are using on a array. I've noted in another part of this topic where I have pages and pages of the data. Forcing me to qualify it with a name when the compiler/structure already knows just seems like an annoyance. True it removes the {}'s, but I think I have 3 levels of deep. S[] s = [S(),S(),S()]; vs S[] s = [{},{},{}]; If they are more complex, then indenting and separation makes sense. And the size of the name I don't want to have to Alias my structures to something tiny and a little obfuscate in order to keep it compact and simple. That's my thoughts anyways. If the language later disallows it, I'll have to change my code to compensate for it.
Apr 28 2012
On 4/29/12, Jonathan M Davis <jmdavisProg gmx.com> wrote:struct S { int field1; float field2; string field3; } then you can do auto s = S(5, 7.2, "hello"); The ability to do S s = {5, 7.2, "hello"}; gains you _nothing_.That's not really the benefit of those initializers. This is: S[] arr = [{field2 = 1.0}, {field2 = 0.5}]; It's a real benefit when unittesting because it allows me to quickly create variables with some interesting state which I can then test.
Apr 28 2012
What's your list?- The is expressions are confusing as hell, and it seems to me that it's serving a purpose that should be handled by __traits (which has its own set of issues in my mind, but is a solid idea) - On the subject, as much as I love __traits(), its dumping grounds nature is problematic. It should be limited to accessing traits of types, or changed to a more representative name. It's not redundant or anything, but is prone to bloating by its design. - I am on the version hate boat. To me, it's redundant with static if(). - as many have said, the comma operator is problematic by nature and should probably go. I haven't been into D for very long, so I'll probably run into more stuff eventually, but that's what comes off the top of my head...
Apr 28 2012
Am 28.04.2012 20:47, schrieb Walter Bright:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- two different ways of creating function pointers is confusing (function and delegate) I understand the reasoning, but makes one think all the time when to use what. - sometimes D code looks like template and mixins gone mad While I do appreciate the power, it can be quite confusing to try to understand what the code does. Specially with the lack of support in mixin's debugging - __traits should be given a proper name It looks out of place in regard with the rest of the language, by making use of the underscores - AA should be a library type I am on the C++ and Scala camp where the language should be extendable via the library - misuse of enum to declare constants I prefer that the use of const would be possible - conditional compilation is hard to follow without syntax highlighting Other languages with conditional compilation make it easier to follow - unit tests I would rather have them as a library. While it is fun to discuss what we like and not like, I vote that priority should be given to make the language stable and have better tooling. We need to have safer languages with native code generation for systems programming in the mainstream OS, that take us away from the buffer overflow exploits and dagling pointers legacy that C and C++ brought upon us. Someone that does not know D and sees the amount of bugs still existing, or this type of discussions, will run away to Go or some future version I don't agree D is complex, any language that aims to be used in large application domains, needs a certain set of abstractions. If it does not support them, it is condemmend to keep getting new features until it turns in what the language designers were fighting against. -- Paulo
Apr 28 2012
On 04/29/2012 08:31 AM, Paulo Pinto wrote:Am 28.04.2012 20:47, schrieb Walter Bright:'delegate' is more powerful, 'function' is more efficient. If you don't want to think about it, just use 'delegate'. I'd rather see 'function' implicitly convert to 'delegate' than to have it gone. D can be used for systems programming after all!Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- two different ways of creating function pointers is confusing (function and delegate) I understand the reasoning, but makes one think all the time when to use what.- sometimes D code looks like template and mixins gone mad While I do appreciate the power, it can be quite confusing to try to understand what the code does. Specially with the lack of support in mixin's debuggingpragma(msg, ...) ?- misuse of enum to declare constants I prefer that the use of const would be possibleconst infects the type and const-qualified data can exist at runtime, so it is not possible.- conditional compilation is hard to follow without syntax highlighting Other languages with conditional compilation make it easier to followThat is not a language issue.While it is fun to discuss what we like and not like, I vote that priority should be given to make the language stable and have better tooling. We need to have safer languages with native code generation for systems programming in the mainstream OS, that take us away from the buffer overflow exploits and dagling pointers legacy that C and C++ brought upon us. Someone that does not know D and sees the amount of bugs still existing, or this type of discussions, will run away to Go or some future version I don't agree D is complex, any language that aims to be used in large application domains, needs a certain set of abstractions. If it does not support them, it is condemmend to keep getting new features until it turns in what the language designers were fighting against.I agree with this section.
Apr 29 2012
Am 29.04.2012 10:42, schrieb Timon Gehr:On 04/29/2012 08:31 AM, Paulo Pinto wrote:That is what I mean. The compiler could make the distinction between function and delegate itself. I am not arguing to remove the feature, rather to have the compiler check it for me. Surely it can see if I am passing the delegate to D code or extern C/C++ code and act accordingly.Am 28.04.2012 20:47, schrieb Walter Bright:'delegate' is more powerful, 'function' is more efficient. If you don't want to think about it, just use 'delegate'. I'd rather see 'function' implicitly convert to 'delegate' than to have it gone. D can be used for systems programming after all!Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- two different ways of creating function pointers is confusing (function and delegate) I understand the reasoning, but makes one think all the time when to use what.Too low level?- sometimes D code looks like template and mixins gone mad While I do appreciate the power, it can be quite confusing to try to understand what the code does. Specially with the lack of support in mixin's debuggingpragma(msg, ...) ?Yeah, but it brings me back bad memories from the early days, when C++ compilers did not fully support C++98, and we had to resort to the enum trick to create constants.- misuse of enum to declare constants I prefer that the use of const would be possibleconst infects the type and const-qualified data can exist at runtime, so it is not possible.How come? In the languages mentioned above, the conditional compilation stands out in clear text that is doing something at compile time. In D you need to be aware which statements are compile time and which are not. Not a big deal to argue about, but easy trap for D newbies. -- Paulo- conditional compilation is hard to follow without syntax highlighting Other languages with conditional compilation make it easier to followThat is not a language issue.
Apr 29 2012
On Sunday, 29 April 2012 at 12:41:37 UTC, Paulo Pinto wrote:I am not arguing to remove the feature, rather to have the compiler check it for me. Surely it can see if I am passing the delegate to D code or extern C/C++ code and act accordingly.How would this work? Function pointers are only a single word in D code as well (and a single unconditional jump to that address) , whereas delegates are two words. What is if a function accepts a delegate, but a function pointer is passed? What is if a delegate is passed to a (possibly C) function – does the compiler automatically emit a thunk for that? David
Apr 29 2012
Am 29.04.2012 15:24, schrieb David Nadlinger:On Sunday, 29 April 2012 at 12:41:37 UTC, Paulo Pinto wrote:Yes, that is what I had in mind. That is what is done in .NET as far as I am aware.I am not arguing to remove the feature, rather to have the compiler check it for me. Surely it can see if I am passing the delegate to D code or extern C/C++ code and act accordingly.How would this work? Function pointers are only a single word in D code as well (and a single unconditional jump to that address) , whereas delegates are two words. What is if a function accepts a delegate, but a function pointer is passed? What is if a delegate is passed to a (possibly C) function – does the compiler automatically emit a thunk for that? David
Apr 29 2012
On 29-04-2012 08:31, Paulo Pinto wrote:Am 28.04.2012 20:47, schrieb Walter Bright:D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?- two different ways of creating function pointers is confusing (function and delegate) I understand the reasoning, but makes one think all the time when to use what. - sometimes D code looks like template and mixins gone mad While I do appreciate the power, it can be quite confusing to try to understand what the code does. Specially with the lack of support in mixin's debugging - __traits should be given a proper name It looks out of place in regard with the rest of the language, by making use of the underscores - AA should be a library type I am on the C++ and Scala camp where the language should be extendable via the library - misuse of enum to declare constants I prefer that the use of const would be possible - conditional compilation is hard to follow without syntax highlighting Other languages with conditional compilation make it easier to follow - unit tests I would rather have them as a library.While it is fun to discuss what we like and not like, I vote that priority should be given to make the language stable and have better tooling. We need to have safer languages with native code generation for systems programming in the mainstream OS, that take us away from the buffer overflow exploits and dagling pointers legacy that C and C++ brought upon us. Someone that does not know D and sees the amount of bugs still existing, or this type of discussions, will run away to Go or some future version I don't agree D is complex, any language that aims to be used in large application domains, needs a certain set of abstractions. If it does not support them, it is condemmend to keep getting new features until it turns in what the language designers were fighting against. -- Paulo-- - Alex
Apr 29 2012
Alex Rønne Petersen:D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.I think D has to offers means to library writers to instrument the built-in unit-testing machinery, to allow the implementation of a good unit testing system. Bye, bearophile
Apr 29 2012
On Sunday, 29 April 2012 at 20:54:11 UTC, Alex Rønne Petersen wrote:What's the problem ? What prevents you to put the unit tests in other modules if you don't want to put them with the code ?- unit tests I would rather have them as a library.D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.
Apr 29 2012
Le 29/04/2012 22:54, Alex Rønne Petersen a écrit :D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.
Apr 29 2012
On Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:Le 29/04/2012 22:54, Alex Rønne Petersen a écrit :The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all. I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda the point, 'cos in my experience the act of writing a unittest automatically makes you think about corner cases in the code you just wrote (or just about to write), which means there will be less bugs from the get-go. Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest. T -- Windows: the ultimate triumph of marketing over technology. -- Adrian von BidderD unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.
Apr 29 2012
On 30-04-2012 05:03, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:The problem with D's unit test support is that it doesn't integrate well into real world build processes. I usually have debug and release configurations, and that's it. No test configuration; not only does that over-complicate things, but it also isn't really useful. I want my unit testing to be exhaustive; i.e. I want to test my code in debug and release builds, because those are the builds people are going to be using. Not a test build. So, this means that writing unit tests inline is a no-go because that would require either always building with unit tests in all configurations (madness) or having a test configuration (see above). Given the above, I've resorted to having a "tester" executable which links in all libraries in my project and tests every module. This means that I have to write my unit tests inside this helper executable, making much of the gain in D's unittest blocks go away. And no, the fact that I link libraries into the helper executable doesn't mean that I can just write the unit tests in the libraries in the first place. Doing so would require building them twice: Once for the normal build and once for the "tester" executable. (And yes, build times matter when your project gets large enough, even in D.) -- - AlexLe 29/04/2012 22:54, Alex Rønne Petersen a écrit :The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all. I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda the point, 'cos in my experience the act of writing a unittest automatically makes you think about corner cases in the code you just wrote (or just about to write), which means there will be less bugs from the get-go. Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest. TD unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.
Apr 29 2012
On Mon, Apr 30, 2012 at 05:16:55AM +0200, Alex Rønne Petersen wrote:On 30-04-2012 05:03, H. S. Teoh wrote:[...][...]Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest.The problem with D's unit test support is that it doesn't integrate well into real world build processes. I usually have debug and release configurations, and that's it. No test configuration; not only does that over-complicate things, but it also isn't really useful. I want my unit testing to be exhaustive; i.e. I want to test my code in debug and release builds, because those are the builds people are going to be using. Not a test build.I see. Personally, I just use a more flexible build system where I can specify an argument to indicate whether or not to compile with -unittest. But you may have other reasons why this is not a good thing.So, this means that writing unit tests inline is a no-go because that would require either always building with unit tests in all configurations (madness) or having a test configuration (see above).I wonder if dmd (or rdmd) should have a mode where it *only* compiles unittest code (i.e., no main() -- the resulting exe just runs unittests and nothing else). But then again, it sounds like you have an extensive testing framework in place, and if you have that already, then might as well use it.Given the above, I've resorted to having a "tester" executable which links in all libraries in my project and tests every module. This means that I have to write my unit tests inside this helper executable, making much of the gain in D's unittest blocks go away. And no, the fact that I link libraries into the helper executable doesn't mean that I can just write the unit tests in the libraries in the first place. Doing so would require building them twice: Once for the normal build and once for the "tester" executable. (And yes, build times matter when your project gets large enough, even in D.)[...] True. T -- "I speak better English than this villain Bush" -- Mohammed Saeed al-Sahaf, Iraqi Minister of Information
Apr 29 2012
On Sunday, April 29, 2012 21:56:08 H. S. Teoh wrote:I wonder if dmd (or rdmd) should have a mode where it *only* compiles unittest code (i.e., no main() -- the resulting exe just runs unittests and nothing else).It wouldn't make sense. It's nowhere near as bad as C++, but dmd has to recompile modules all the time unless you compile the entire program at once. When you run a build, every single module on the command line and all of the imported modules get compiled. Object code is generated only for those on the command line, but the others are still compiled. Any imported module which uses a .di file won't have as much to compile, and any templated code that doesn't get used in those modules won't get compiled, but there's still lots of recompilation going on if you compile your program incrementally. And D just isn't set up to compile only a portion of a module. - Jonathan M Davis
Apr 29 2012
On 04/30/2012 07:03 AM, Jonathan M Davis wrote:On Sunday, April 29, 2012 21:56:08 H. S. Teoh wrote:Only the symbols that need to be analysed actually get analysed (eg. CTFE, instantiated templates.) The other symbols are merely parsed, and parsing is quite cheap.I wonder if dmd (or rdmd) should have a mode where it *only* compiles unittest code (i.e., no main() -- the resulting exe just runs unittests and nothing else).It wouldn't make sense. It's nowhere near as bad as C++, but dmd has to recompile modules all the time unless you compile the entire program at once. When you run a build, every single module on the command line and all of the imported modules get compiled.Object code is generated only for those on the command line, but the others are still compiled.I think 'compiled' would imply that some output code is generated.Any imported module which uses a .di file won't have as much to compile,There is no difference between .d files and .di files except that the compiler prefers the .di file for imports.and any templated code that doesn't get used in those modules won't get compiled, but there's still lots of recompilation going on if you compile your program incrementally.It depends on how much CTFE is performed on the module interface level.And DDMD.just isn't set up to compile only a portion of a module. - Jonathan M DavisIf that is necessary then the module is too big.
Apr 30 2012
On 4/30/12, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Sunday, April 29, 2012 21:56:08 H. S. Teoh wrote:For RDMD you can do: version(unittest) { } else void main() { // regular code here } And then you can invoke rdmd with --unittest and --main to insert an empty main function when unittesting. Personally I put in a stub main so I don't depend on rdmd features like --main: version(unittest) { void main(string[] args) { } } // stub main else void main() { // regular code here }I wonder if dmd (or rdmd) should have a mode where it *only* compiles unittest code (i.e., no main() -- the resulting exe just runs unittests and nothing else).
Apr 29 2012
On Monday, 30 April 2012 at 03:16:57 UTC, Alex Rønne Petersen wrote:The problem with D's unit test support is that it doesn't integrate well into real world build processes. I usually have debug and release configurations, and that's it. No test configuration; not only does that over-complicate things, but it also isn't really useful. I want my unit testing to be exhaustive; i.e. I want to test my code in debug and release builds, because those are the builds people are going to be using. Not a test build. So, this means that writing unit tests inline is a no-go because that would require either always building with unit tests in all configurations (madness) or having a test configuration (see above). Given the above, I've resorted to having a "tester" executable which links in all libraries in my project and tests every module. This means that I have to write my unit tests inside this helper executable, making much of the gain in D's unittest blocks go away. And no, the fact that I link libraries into the helper executable doesn't mean that I can just write the unit tests in the libraries in the first place. Doing so would require building them twice: Once for the normal build and once for the "tester" executable.OK, that makes sense. What a test framework could do, although it's kind of ugly, is first copy the unittest() sections into separate test files, compile them and then link with the tested module code. You would keep the advantage of having test code close to source code, and still compile the real code without -unittest switch.(And yes, build times matter when your project gets large enough, even in D.)Just for information, how big is your project (how many files), and how long does a full build take ? I have no idea how fast the compiler really is (is it GDC or DMD you are using ?).
Apr 30 2012
On 30-04-2012 11:46, SomeDude wrote:On Monday, 30 April 2012 at 03:16:57 UTC, Alex Rønne Petersen wrote:I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC. -- - AlexThe problem with D's unit test support is that it doesn't integrate well into real world build processes. I usually have debug and release configurations, and that's it. No test configuration; not only does that over-complicate things, but it also isn't really useful. I want my unit testing to be exhaustive; i.e. I want to test my code in debug and release builds, because those are the builds people are going to be using. Not a test build. So, this means that writing unit tests inline is a no-go because that would require either always building with unit tests in all configurations (madness) or having a test configuration (see above). Given the above, I've resorted to having a "tester" executable which links in all libraries in my project and tests every module. This means that I have to write my unit tests inside this helper executable, making much of the gain in D's unittest blocks go away. And no, the fact that I link libraries into the helper executable doesn't mean that I can just write the unit tests in the libraries in the first place. Doing so would require building them twice: Once for the normal build and once for the "tester" executable.OK, that makes sense. What a test framework could do, although it's kind of ugly, is first copy the unittest() sections into separate test files, compile them and then link with the tested module code. You would keep the advantage of having test code close to source code, and still compile the real code without -unittest switch.(And yes, build times matter when your project gets large enough, even in D.)Just for information, how big is your project (how many files), and how long does a full build take ? I have no idea how fast the compiler really is (is it GDC or DMD you are using ?).
Apr 30 2012
On Monday, 30 April 2012 at 15:19:29 UTC, Alex Rønne Petersen wrote:On 30-04-2012 11:46, SomeDude wrote: I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.For how many files/lines of code ?
Apr 30 2012
On Monday, 30 April 2012 at 16:14:58 UTC, SomeDude wrote:On Monday, 30 April 2012 at 15:19:29 UTC, Alex Rønne Petersen wrote:And on what hardware ? I'd like to have a bit of an idea of how fast the compilers really are.On 30-04-2012 11:46, SomeDude wrote: I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.For how many files/lines of code ?
Apr 30 2012
On 30 April 2012 17:16, SomeDude <lovelydear mailmetrash.com> wrote:On Monday, 30 April 2012 at 16:14:58 UTC, SomeDude wrote:That sort of speed difference sounds about right. I'm not sure how the DMD backend works, but I assume that there is no more than about 3 passes. A conversion from D Frontend AST to DM Backend AST, possibly a peephole optimiser, then an output to object code. GCC backend has some 50+ passes it processes the generated AST through passed from GDC. Not to mention it only outputs assembly code. So there is some overhead for calling AS to compile to object code (something that DMD just compiles straight to), and double overhead for calling LD to link the resultant binary/library. Regards --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';On Monday, 30 April 2012 at 15:19:29 UTC, Alex R=F8nne Petersen wrote:And on what hardware ? I'd like to have a bit of an idea of how fast the compilers really are.On 30-04-2012 11:46, SomeDude wrote: I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.For how many files/lines of code ?
Apr 30 2012
On 2012-04-30 18:44, Iain Buclaw wrote:GCC backend has some 50+ passes it processes the generated AST through passed from GDC. Not to mention it only outputs assembly code. So there is some overhead for calling AS to compile to object code (something that DMD just compiles straight to), and double overhead for calling LD to link the resultant binary/library.DMD calls GCC which calls LD. Unless your using the -lib flag. -- /Jacob Carlborg
Apr 30 2012
On 30 April 2012 17:44, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 30 April 2012 17:16, SomeDude <lovelydear mailmetrash.com> wrote:Having said that, I did produce a report from GDC once with a list of times it takes to compile D2 code (in this instance, libphobos and druntime). http://iainbuclaw.files.wordpress.com/2010/09/d2-time-report2.pdf TOTAL is the total time taken (ie: 0.08 seconds in the first file), and the other elements are a breakdown of what passes took the longest amount of processing time during the entire compilation. If you could get DMD to pull off a similar report, you'd have something nice to compare to. ;-) Regards --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';On Monday, 30 April 2012 at 16:14:58 UTC, SomeDude wrote:That sort of speed difference sounds about right. =A0I'm not sure how the DMD backend works, but I assume that there is no more than about 3 passes. =A0A conversion from D Frontend AST to DM Backend AST, possibly a peephole optimiser, then an output to object code. GCC backend has some 50+ passes it processes the generated AST through passed from GDC. Not to mention it only outputs assembly code. =A0So there is some overhead for calling AS to compile to object code (something that DMD just compiles straight to), and double overhead for calling LD to link the resultant binary/library.On Monday, 30 April 2012 at 15:19:29 UTC, Alex R=F8nne Petersen wrote:And on what hardware ? I'd like to have a bit of an idea of how fast the compilers really are.On 30-04-2012 11:46, SomeDude wrote: I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.For how many files/lines of code ?
Apr 30 2012
On Monday, 30 April 2012 at 16:54:48 UTC, Iain Buclaw wrote:Having said that, I did produce a report from GDC once with a list of times it takes to compile D2 code (in this instance, libphobos and druntime). http://iainbuclaw.files.wordpress.com/2010/09/d2-time-report2.pdf TOTAL is the total time taken (ie: 0.08 seconds in the first file), and the other elements are a breakdown of what passes took the longest amount of processing time during the entire compilation. If you could get DMD to pull off a similar report, you'd have something nice to compare to. ;-) RegardsThx, that's interesting.
Apr 30 2012
On 4/30/12, SomeDude <lovelydear mailmetrash.com> wrote:I'd like to have a bit of an idea of how fast the compilers really are.Personally my gripe with compilation times is that I get very used to having fast build times where I can go through an edit+compile+run cycle really fast, but after a while build times get slower (especially when templates get in the mix) and this really throws me off. Sometimes I wish I could just interpret D code at runtime just to save on compilation time, because I might just be testing the semantics of code and not necessarily its performance at a time.
Apr 30 2012
On Monday, 30 April 2012 at 19:08:54 UTC, Andrej Mitrovic wrote:On 4/30/12, SomeDude <lovelydear mailmetrash.com> wrote:Yeah, templates is what slows everything down. I'd be very wary of using Boost in C++, for instance, because heavy usage of templates in C++ can slow your development cycle to a crawl in a large project. But in D, the risk of recompilation is limited by the module system, right ?I'd like to have a bit of an idea of how fast the compilers really are.Personally my gripe with compilation times is that I get very used to having fast build times where I can go through an edit+compile+run cycle really fast, but after a while build times get slower (especially when templates get in the mix) and this really throws me off. Sometimes I wish I could just interpret D code at runtime just to save on compilation time, because I might just be testing the semantics of code and not necessarily its performance at a time.
Apr 30 2012
On Monday, 30 April 2012 at 21:11:20 UTC, SomeDude wrote:But in D, the risk of recompilation is limited by the module system, right ?Also, in D, bugs in the CTFE slows everything down, in particular this one: http://d.puremagic.com/issues/show_bug.cgi?id=6498
Apr 30 2012
On 4/30/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Personally my gripe with compilation times is that I get very used to having fast build times where I can go through an edit+compile+run cycle really fast, but after a while build times get slowerAlso since 2.059 error reporting is *completely* broken. I have to wait 5 seconds just to get this error message itself to print to the screen: http://pastebin.com/y93GEPAf 500 lines of errors even though only the first line is an actual error. What in the actual fuck are all those other error messages? The only problem was this line in a main file: CppGen gen; and CppGen was undefined because I've missed an import. And if I remove the only import left (std.range), I get much less garbage but I still get unrelated errors: main.d(80): Error: undefined identifier CppGen D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template std.conv.toImpl does not match any function template declaration D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template std.conv.toImpl cannot deduce template function from argument types !(string)(long) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template instance toImpl!(string) errors instantiating template loader\gcc.d(167): Error: template instance std.conv.to!(string).to!(long) error instantiating 2.058 error reporting worked fine, I don't know what someone did to screw this up so massively.
May 08 2012
On 08/05/12 09:56, Andrej Mitrovic wrote:On 4/30/12, Andrej Mitrovic<andrej.mitrovich gmail.com> wrote:That bug was fixed in git not long after release. Unfortunately it seems that there are not enough people doing beta testing. As for why it happened -- previously the compiler used a hack to prevent the flood of error messages (and the hack didn't work properly in the case where errors were gagged, like in is(typeof()) ). Now it does it properly.Personally my gripe with compilation times is that I get very used to having fast build times where I can go through an edit+compile+run cycle really fast, but after a while build times get slowerAlso since 2.059 error reporting is *completely* broken. I have to wait 5 seconds just to get this error message itself to print to the screen: http://pastebin.com/y93GEPAf 500 lines of errors even though only the first line is an actual error. What in the actual fuck are all those other error messages? The only problem was this line in a main file: CppGen gen; and CppGen was undefined because I've missed an import. And if I remove the only import left (std.range), I get much less garbage but I still get unrelated errors: main.d(80): Error: undefined identifier CppGen D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template std.conv.toImpl does not match any function template declaration D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template std.conv.toImpl cannot deduce template function from argument types !(string)(long) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(244): Error: template instance toImpl!(string) errors instantiating template loader\gcc.d(167): Error: template instance std.conv.to!(string).to!(long) error instantiating 2.058 error reporting worked fine, I don't know what someone did to screw this up so massively.
May 08 2012
On 5/8/12, Don Clugston <dac nospam.com> wrote:That bug was fixed in git not long after release.I still get it with this version: http://d.puremagic.com/test-results/test_data.ghtml?dataid=180993 Same errors: http://pastebin.com/8uqgskHd
May 08 2012
On 08/05/12 14:50, Andrej Mitrovic wrote:On 5/8/12, Don Clugston<dac nospam.com> wrote:OK, looks like it's a different bug. Please put in bugzilla, with status of regression.That bug was fixed in git not long after release.I still get it with this version: http://d.puremagic.com/test-results/test_data.ghtml?dataid=180993 Same errors: http://pastebin.com/8uqgskHd
May 09 2012
On 5/9/12, Don Clugston <dac nospam.com> wrote:OK, looks like it's a different bug. Please put in bugzilla, with status of regression.It turns out it's not a regression: http://d.puremagic.com/issues/show_bug.cgi?id=8082 Something odd about module compilation order which makes unrelated modules error out.
May 11 2012
On 5/11/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:It turns out it's not a regression: http://d.puremagic.com/issues/show_bug.cgi?id=8082 Something odd about module compilation order which makes unrelated modules error out.In my project making sure my main.d file is compiled *last* reduces the error count from ~400 lines to just 2 error lines.
May 11 2012
On 2012-04-30 05:16, Alex Rønne Petersen wrote:On 30-04-2012 05:03, H. S. Teoh wrote:-- /Jacob CarlborgOn Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:The problem with D's unit test support is that it doesn't integrate well into real world build processes. I usually have debug and release configurations, and that's it. No test configuration; not only does that over-complicate things, but it also isn't really useful. I want my unit testing to be exhaustive; i.e. I want to test my code in debug and release builds, because those are the builds people are going to be using. Not a test build. So, this means that writing unit tests inline is a no-go because that would require either always building with unit tests in all configurations (madness) or having a test configuration (see above). Given the above, I've resorted to having a "tester" executable which links in all libraries in my project and tests every module. This means that I have to write my unit tests inside this helper executable, making much of the gain in D's unittest blocks go away. And no, the fact that I link libraries into the helper executable doesn't mean that I can just write the unit tests in the libraries in the first place. Doing so would require building them twice: Once for the normal build and once for the "tester" executable. (And yes, build times matter when your project gets large enough, even in D.)Le 29/04/2012 22:54, Alex Rønne Petersen a écrit :The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all. I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda the point, 'cos in my experience the act of writing a unittest automatically makes you think about corner cases in the code you just wrote (or just about to write), which means there will be less bugs from the get-go. Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest. TD unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.
Apr 30 2012
Le 30/04/2012 05:03, H. S. Teoh a écrit :On Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:Is unittest on top of a function much more difficult ?Le 29/04/2012 22:54, Alex Rønne Petersen a écrit :The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all.D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda the point, 'cos in my experience the act of writing a unittest automatically makes you think about corner cases in the code you just wrote (or just about to write), which means there will be less bugs from the get-go.Agreed.Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest.Consider cases like checking if Liskov substitution principle is fallowed in a class hierarchy running the same unitest on various instantiations in that hierarchy. This is common need and still fall in the unittest bag.
Apr 30 2012
On Sunday, April 29, 2012 20:03:44 H. S. Teoh wrote:On Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:ldLe 29/04/2012 22:54, Alex R=C3=B8nne Petersen a =C3=A9crit :D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-wor=he=20 The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all. =20 I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda t=application projects with lots of libraries and executables.=20 +1 A good std.unittest + attributes is probably a better approach.point, 'cos in my experience the act of writing a unittest automatica=llymakes you think about corner cases in the code you just wrote (or jus=tabout to write), which means there will be less bugs from the get-go.==20 Also, unittest is just that: for _unit_ tests. If you start needing a=nentire framework for them, then you're no longer talking about _unit_=tests, you're talking about module- or package-level testing framewor=ks,and you should be using something more suitable for that, not unittes=t. One common term for those is "component tests." Unit tests are for test= ing=20 individual functions and types, whereas component tests test inter-modu= le and=20 inter-program interactions. What D has with regards to unit tests works _very_ well for basic unit = tests=20 but does not attempt to support component tests at all beyond where uni= ttest=20 blocks could be used for the same purpose. The main place that D's unit= test=20 framework becomes problematic is when you need to run a subset of tests= - it's=20 designed to run everything at once. But compiling and running each modu= le=20 separately for unit tests allows you to control that through you build = system=20 or whatnot. As Walter has stated on several occasions, D's built-in unit testing fr= amework=20 is designed to be incredibly simple and easy so that they're so easy an= d=20 convenient to use that you have no excuse not to. If you want more comp= licated=20 unit testing frameworks, there's nothing stopping you from making your = own=20 like has to be done in other languges. For instance, cppunit and junit = aren't=20 built-in to their associated languages at all; they're 3rd party projec= ts. You=20 can do the same in D if you want fancier unit testing facilities. - Jonathan M Davis
Apr 29 2012
On 30-04-2012 05:12, Jonathan M Davis wrote:On Sunday, April 29, 2012 20:03:44 H. S. Teoh wrote:Except we can't do: test void myTest() { // ... } due to the current lack of annotations and discovery-based reflection. ;) *hint hint...* -- - AlexOn Sun, Apr 29, 2012 at 11:39:02PM +0200, deadalnix wrote:One common term for those is "component tests." Unit tests are for testing individual functions and types, whereas component tests test inter-module and inter-program interactions. What D has with regards to unit tests works _very_ well for basic unit tests but does not attempt to support component tests at all beyond where unittest blocks could be used for the same purpose. The main place that D's unit test framework becomes problematic is when you need to run a subset of tests - it's designed to run everything at once. But compiling and running each module separately for unit tests allows you to control that through you build system or whatnot. As Walter has stated on several occasions, D's built-in unit testing framework is designed to be incredibly simple and easy so that they're so easy and convenient to use that you have no excuse not to. If you want more complicated unit testing frameworks, there's nothing stopping you from making your own like has to be done in other languges. For instance, cppunit and junit aren't built-in to their associated languages at all; they're 3rd party projects. You can do the same in D if you want fancier unit testing facilities. - Jonathan M DavisLe 29/04/2012 22:54, Alex Rønne Petersen a écrit :The only reason I actually write unittests for D code is because unittest{} is so convenient. If I had to import std.unittest, most likely my code will have no unittests at all. I find that because unittest{} makes it so convenient to write unittests, it's just embarrassing to not write them. Which is kinda the point, 'cos in my experience the act of writing a unittest automatically makes you think about corner cases in the code you just wrote (or just about to write), which means there will be less bugs from the get-go. Also, unittest is just that: for _unit_ tests. If you start needing an entire framework for them, then you're no longer talking about _unit_ tests, you're talking about module- or package-level testing frameworks, and you should be using something more suitable for that, not unittest.D unit tests were never really useful for anything beyond single-library projects IMHO. They don't scale for large, real-world application projects with lots of libraries and executables.+1 A good std.unittest + attributes is probably a better approach.
Apr 29 2012
On Monday, April 30, 2012 05:20:21 Alex R=C3=B8nne Petersen wrote:Except we can't do: =20 test void myTest() { // ... } =20 due to the current lack of annotations and discovery-based reflection=. ;)=20 *hint hint...*What would that buy you? That's what unittest blocks are for. Yes, gett= ing=20 custom annotations would be great, and then you could use test for wha= tever=20 you need it for, but unittest blocks are the test functions, so I'm not= quite=20 sure what test would buy you. You _could_ just put a particular string= in a=20 name though (e.g. start all unit test functions with test) and use comp= ile- time reflection to find them if you really want to though (much as that= isn't as=20 nice as a user-defined attribute would be). - Jonathan M Davis
Apr 29 2012
On 30-04-2012 05:34, Jonathan M Davis wrote:On Monday, April 30, 2012 05:20:21 Alex Rønne Petersen wrote:See my other reply to H. S. Teoh for why I'm not a fan of unittest blocks. -- - AlexExcept we can't do: test void myTest() { // ... } due to the current lack of annotations and discovery-based reflection. ;) *hint hint...*What would that buy you? That's what unittest blocks are for. Yes, getting custom annotations would be great, and then you could use test for whatever you need it for, but unittest blocks are the test functions, so I'm not quite sure what test would buy you. You _could_ just put a particular string in a name though (e.g. start all unit test functions with test) and use compile- time reflection to find them if you really want to though (much as that isn't as nice as a user-defined attribute would be). - Jonathan M Davis
Apr 29 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?garbage collector *duck and run* The point I'm trying to make is... normally I would use around 4-5 different languages depending on _what_ problem I'm currently solving... occasionally even languages I'm not particularly proficient with, just because a language might have an edge in a certain domain... however 'D' basically is good enough at "everything"... with some few exceptions. So what one person considers redundant, is integral to someone else with a different background... no, D doesn't have too many features.
Apr 29 2012
On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:What's your list?My personal list of features I could easily live without – some of these might be controversial, but yes, I have written non-trivial amounts of code in both D1 and D2: - Anonymous nested classes: They might be useful in Java, particularly in older incarnations, but not so much in D – never used them. - Comma operator: Kill it with extreme prejudice, it is an anti-feature (allow it in for loop expressions if you really want to, but I think there are better solutions). - Typesafe variadics: They look nice on paper, but I haven't used them once. Often, you either explicitly need C-style variadics, or you want to accept e.g. multiple ranges of the same element type, where you need template variadics anyway. - Unsigned right shift, but I can see how it can be useful (simply underused?). - HexString, DelimitedString, r""-WysiwigString, TokenString: I didn't ever use the former two (for including binary data in the program, ImportExpression is imho much easier than generating a source file containing a HexString). As for r"", every time I actually need WysiwigString, I use backticks, because such strings often contain quotes anyway. Regarding TokenString(i.e. q{}) – it is certainly a very nice idea, especially regarding syntax highlighting, and I occasionally use them for CTFE code generation. But without any kind of support for string interpolation, I typically find myself using normal strings for everything except small self-contained portions of code (where mixin templates would probably be cleaner). The problem is that can't just »interrupt« q{}s strings to do something like »q{…} ~ identifierName ~ q{…}«, because there will most likely be unmatched braces – but this is needed in assembling mixin strings all the time… - Concatenation of adjacent strings: Also an anti-feature, imho. - Floating point comparison operators like !<>= (yes, that _is_ valid D code): I must admit that I seldom write code relying on the finer details of IEEE-754 semantics, but can't they just be »lowered« to a combination of the more common ones? - »Short« floating point literals like .4 instead of 0.4 and 4. instead of 4.0 – the saved characters are not worth the syntax special cases, especially w.r.t. UFCS. - new/delete issues have been discussed many times - Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs. - shared: TLS by default is great, but only __gshared is really usable right now. IMHO, shared had better been reserved for a comprehensive take on the subject, rather than the half-baked implementation we have right now. David
Apr 29 2012
On 04/29/2012 02:26 PM, David Nadlinger wrote:TokenString: [...]Regarding TokenString(i.e. q{}) – it is certainly a very nice idea, especially regarding syntax highlighting, and I occasionally use them for CTFE code generation. But without any kind of support for string interpolation, I typically find myself using normal strings for everything except small self-contained portions of code (where mixin templates would probably be cleaner). The problem is that can't just »interrupt« q{}s strings to do something like »q{…} ~ identifierName ~ q{…}«, because there will most likely be unmatched braces – but this is needed in assembling mixin strings all the time…Lack of string interpolation is not a reason to kill the token string, because CTFE lets you provide the interpolation manually. I use token strings often in this fashion for code generation.- Floating point comparison operators like !<>= (yes, that _is_ valid D code): I must admit that I seldom write code relying on the finer details of IEEE-754 semantics, but can't they just be »lowered« to a combination of the more common ones?I kinda like those ;D.
Apr 29 2012
On Sunday, 29 April 2012 at 12:26:13 UTC, David Nadlinger wrote:- Anonymous nested classes: They might be useful in Java, particularly in older incarnations, but not so much in D – never used them.I never used these until very recently. A couple weeks ago, I wanted to do some kind of range adapter kinda like Phobos does with the anon structs... but I wanted it to work with runtime too. So, I made an interface with empty, front, popFront, and then pulled out the old "return new class ByChunkRange" for the first time. I never expected that I'd use it, but it was nice to have for that time when I did decide I wanted it. That's my biggest concern with saying we have too many features. We might not use them often, but it would suck to say "that would be perfect" just to find it was removed later.
Apr 29 2012
On 4/29/12, David Nadlinger <see klickverbot.at> wrote:As for r"", every time I actually need WysiwigString, I use backticks, because such strings often contain quotes anyway.IIRC I think the reason for this might be that some keyboards don't have the backtick key, or something like that.Regarding TokenString(i.e. q{}) .. The problem is that can't just =BBinterrupt=AB q{}s strings to do something like =BBq{=85} ~ identifierName ~ q{=85}=AB,I typically use format for these purposes, e.g.: string x =3D format(q{ void %s() { } }, "foo"); Works fairly well for me.- Concatenation of adjacent strings: Also an anti-feature, imho.Absolutely!- =BBShort=AB floating point literals like .4 instead of 0.4 and 4. instead of 4.0 =96 the saved characters are not worth the syntax special cases, especially w.r.t. UFCS.I think those are already deprecated? Or they're about to be anyway.- shared: TLS by default is great, but only __gshared is really usable right now.Yep, and Phobos doesn't deal with shared all that well either. E.g. format() doesn't work on shared variables (http://d.puremagic.com/issues/show_bug.cgi?id=3D7036).
Apr 29 2012
Andrej Mitrovic:I have asked for it, but currently there are no plans in deprecating them, please vote if you agree and you have free votes left (already 7 votes! It's a lot): http://d.puremagic.com/issues/show_bug.cgi?id=6277 Bye, bearophile- »Short« floating point literals like .4 instead of 0.4 and 4. instead of 4.0 – the saved characters are not worth the syntax special cases, especially w.r.t. UFCS.I think those are already deprecated? Or they're about to be anyway.
Apr 29 2012
On 4/29/12, bearophile <bearophileHUGS lycos.com> wrote:I have asked for it, but currently there are no plans in deprecating them, please vote if you agree and you have free votes left (already 7 votes! It's a lot):Well I assumed they're on the way to deprecation when I've read this: http://dlang.org/changelog.html#new2_058: "Allow 1.userproperty syntax. NOTE: 1.f is no longer a float literal, add a 0."
Apr 29 2012
On Sunday, 29 April 2012 at 12:26:13 UTC, David Nadlinger wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:What I forgot to mention: - VersionCondition: Just provide a mechanism to map command line flags to constants, probably in a magic »version« namespace, and use static if (e.g. »version (Foo)« -> »static if (version.Foo)«, »version (unittest)« -> »static if (unittest)«). - DebugCondition: Hardly used in practice, at least not in ways that couldn't easily be replaced with a static if (resp. version). It is a frequent source of confusion for newcomers that -debug is orthogonal to -O/-release, and I'm not too fond of the purity »escape hatch« built in (why not just use casts in those rare cases?). DavidWhat's your list?My personal list of features I could easily live without – some of these might be controversial, but yes, I have written non-trivial amounts of code in both D1 and D2:
Apr 29 2012
On 29-04-2012 21:19, David Nadlinger wrote:On Sunday, 29 April 2012 at 12:26:13 UTC, David Nadlinger wrote:Something like that seems reasonable. At any rate, version in its current state is not very useful in practice.On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:What I forgot to mention: - VersionCondition: Just provide a mechanism to map command line flags to constants, probably in a magic »version« namespace, and use static if (e.g. »version (Foo)« -> »static if (version.Foo)«, »version (unittest)« -> »static if (unittest)«).What's your list?My personal list of features I could easily live without – some of these might be controversial, but yes, I have written non-trivial amounts of code in both D1 and D2:- DebugCondition: Hardly used in practice, at least not in ways that couldn't easily be replaced with a static if (resp. version). It is a frequent source of confusion for newcomers that -debug is orthogonal to -O/-release, and I'm not too fond of the purity »escape hatch« built in (why not just use casts in those rare cases?).+1. And debug being a keyword is more annoying than you'd think.David-- - Alex
Apr 29 2012
On Sunday, 29 April 2012 at 19:19:51 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 12:26:13 UTC, David Nadlinger wrote: What I forgot to mention: - VersionCondition: Just provide a mechanism to map command line flags to constants, probably in a magic »version« namespace, and use static if (e.g. »version (Foo)« -> »static if (version.Foo)«, »version (unittest)« -> »static if (unittest)«).It sounds indeed nice, but I prefer convention over configuration. Experience has shown that it makes things simpler.
Apr 29 2012
On Sunday, 29 April 2012 at 21:23:41 UTC, SomeDude wrote:On Sunday, 29 April 2012 at 19:19:51 UTC, David Nadlinger wrote:What exactly does this have to do with »convention over configuration«? The big problem with version conditionals is that they introduce a heavily restricted subset of static if, i.e. a whole new language construct, for questionable benefits. DavidWhat I forgot to mention: - VersionCondition: Just provide a mechanism to map command line flags to constants, probably in a magic »version« namespace, and use static if (e.g. »version (Foo)« -> »static if (version.Foo)«, »version (unittest)« -> »static if (unittest)«).It sounds indeed nice, but I prefer convention over configuration. Experience has shown that it makes things simpler.
Apr 29 2012
On 29-04-2012 14:26, David Nadlinger wrote:On Saturday, 28 April 2012 at 18:48:18 UTC, Walter Bright wrote:I use them. They can be useful when you're writing more object-oriented code than functional style code.What's your list?My personal list of features I could easily live without – some of these might be controversial, but yes, I have written non-trivial amounts of code in both D1 and D2: - Anonymous nested classes: They might be useful in Java, particularly in older incarnations, but not so much in D – never used them.- Comma operator: Kill it with extreme prejudice, it is an anti-feature (allow it in for loop expressions if you really want to, but I think there are better solutions).+9001.- Typesafe variadics: They look nice on paper, but I haven't used them once. Often, you either explicitly need C-style variadics, or you want to accept e.g. multiple ranges of the same element type, where you need template variadics anyway. - Unsigned right shift, but I can see how it can be useful (simply underused?).It's clear that arithmetic right shift is what the programmer usually wants, and yet, we use >> to denote what they don't want. It's completely counter-intuitive. So, +1.- HexString, DelimitedString, r""-WysiwigString, TokenString: I didn't ever use the former two (for including binary data in the program, ImportExpression is imho much easier than generating a source file containing a HexString). As for r"", every time I actually need WysiwigString, I use backticks, because such strings often contain quotes anyway. Regarding TokenString(i.e. q{}) – it is certainly a very nice idea, especially regarding syntax highlighting, and I occasionally use them for CTFE code generation. But without any kind of support for string interpolation, I typically find myself using normal strings for everything except small self-contained portions of code (where mixin templates would probably be cleaner). The problem is that can't just »interrupt« q{}s strings to do something like »q{…} ~ identifierName ~ q{…}«, because there will most likely be unmatched braces – but this is needed in assembling mixin strings all the time… - Concatenation of adjacent strings: Also an anti-feature, imho.+1.- Floating point comparison operators like !<>= (yes, that _is_ valid D code): I must admit that I seldom write code relying on the finer details of IEEE-754 semantics, but can't they just be »lowered« to a combination of the more common ones?Why not just make them intrinsics? What are they doing in the language? You're rarely, if ever, going to actually be using these operators because NaN is, well, an invalid state, like null. +1.- »Short« floating point literals like .4 instead of 0.4 and 4. instead of 4.0 – the saved characters are not worth the syntax special cases, especially w.r.t. UFCS.+1. I find it to be poor style to not include the ".0" in FP literals.- new/delete issues have been discussed many times - Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs.Sounds reasonable.- shared: TLS by default is great, but only __gshared is really usable right now. IMHO, shared had better been reserved for a comprehensive take on the subject, rather than the half-baked implementation we have right now. DavidIt's clear that shared is biased towards heavily templatized code. It's not useful in non-templatized code because such code can't accept both shared and non-shared values. shared looks neat in theory, but is a fallacy in practice. -- - Alex
Apr 29 2012
On 04/29/2012 10:59 PM, Alex Rønne Petersen wrote:On 29-04-2012 14:26, David Nadlinger wrote:'>>' is arithmetic right shift.- Unsigned right shift, but I can see how it can be useful (simply underused?).It's clear that arithmetic right shift is what the programmer usually wants, and yet, we use >> to denote what they don't want. It's completely counter-intuitive. So, +1.Just cast it away if you do eg. locking. There is nothing wrong with it. Code that operates on both (actually) shared and unshared data should be uncommon anyway.- shared: TLS by default is great, but only __gshared is really usable right now. IMHO, shared had better been reserved for a comprehensive take on the subject, rather than the half-baked implementation we have right now. DavidIt's clear that shared is biased towards heavily templatized code. It's not useful in non-templatized code because such code can't accept both shared and non-shared values.shared looks neat in theory, but is a fallacy in practice.unshared is what is important. There is no unshared if there is no shared.
Apr 29 2012
On 30-04-2012 00:08, Timon Gehr wrote:On 04/29/2012 10:59 PM, Alex Rønne Petersen wrote:Sorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.On 29-04-2012 14:26, David Nadlinger wrote:'>>' is arithmetic right shift.- Unsigned right shift, but I can see how it can be useful (simply underused?).It's clear that arithmetic right shift is what the programmer usually wants, and yet, we use >> to denote what they don't want. It's completely counter-intuitive. So, +1.The problem is that shared is supposed to insert memory barriers (I know it doesn't, but that's the goal/idea).Just cast it away if you do eg. locking. There is nothing wrong with it. Code that operates on both (actually) shared and unshared data should be uncommon anyway.- shared: TLS by default is great, but only __gshared is really usable right now. IMHO, shared had better been reserved for a comprehensive take on the subject, rather than the half-baked implementation we have right now. DavidIt's clear that shared is biased towards heavily templatized code. It's not useful in non-templatized code because such code can't accept both shared and non-shared values.I think this statement went over my head... -- - Alexshared looks neat in theory, but is a fallacy in practice.unshared is what is important. There is no unshared if there is no shared.
Apr 29 2012
Sorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.It does arithmetic shift if the left operand is signed, unsigned shift otherwise. This code: void main() { int a = 0xffffffff; uint b = a; writefln("%x", a >> 1); writefln("%x", b >> 1); } prints ffffffff 7fffffff
Apr 29 2012
On 30-04-2012 08:37, jerro wrote:The documentation disagrees: http://dlang.org/expression.html#ShiftExpression It claims that it always does arithmetic shift and >>> always does unsigned shift. -- - AlexSorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.It does arithmetic shift if the left operand is signed, unsigned shift otherwise. This code: void main() { int a = 0xffffffff; uint b = a; writefln("%x", a >> 1); writefln("%x", b >> 1); } prints ffffffff 7fffffff
Apr 30 2012
On 04/30/2012 05:21 PM, Alex Rønne Petersen wrote:On 30-04-2012 08:37, jerro wrote:http://d.puremagic.com/issues/show_bug.cgi?id=8007The documentation disagrees: http://dlang.org/expression.html#ShiftExpression It claims that it always does arithmetic shift and >>> always does unsigned shift.Sorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.It does arithmetic shift if the left operand is signed, unsigned shift otherwise. This code: void main() { int a = 0xffffffff; uint b = a; writefln("%x", a >> 1); writefln("%x", b >> 1); } prints ffffffff 7fffffff
Apr 30 2012
On 30-04-2012 20:17, Timon Gehr wrote:On 04/30/2012 05:21 PM, Alex Rønne Petersen wrote:Thanks; these kinds of documentation bugs can cause really nasty misunderstandings. -- - AlexOn 30-04-2012 08:37, jerro wrote:http://d.puremagic.com/issues/show_bug.cgi?id=8007The documentation disagrees: http://dlang.org/expression.html#ShiftExpression It claims that it always does arithmetic shift and >>> always does unsigned shift.Sorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.It does arithmetic shift if the left operand is signed, unsigned shift otherwise. This code: void main() { int a = 0xffffffff; uint b = a; writefln("%x", a >> 1); writefln("%x", b >> 1); } prints ffffffff 7fffffff
Apr 30 2012
On 04/30/2012 08:30 PM, Alex Rønne Petersen wrote:On 30-04-2012 20:17, Timon Gehr wrote:I don't trust the documentation. In my experience, it is usually best to rely on common sense to get a grasp for how a feature is supposed to behave (that works surprisingly well!) and occasionally file bug reports if either the documentation or DMD is strange in a certain aspect. (I'll probably file a bunch of implicit-conversion related bugs tomorrow.)On 04/30/2012 05:21 PM, Alex Rønne Petersen wrote:Thanks; these kinds of documentation bugs can cause really nasty misunderstandings.On 30-04-2012 08:37, jerro wrote:http://d.puremagic.com/issues/show_bug.cgi?id=8007The documentation disagrees: http://dlang.org/expression.html#ShiftExpression It claims that it always does arithmetic shift and >>> always does unsigned shift.Sorry, I managed to get myself confused here. What I meant to say was that I think >> should do an arithmetic shift if the operands are signed; unsigned shift otherwise.It does arithmetic shift if the left operand is signed, unsigned shift otherwise. This code: void main() { int a = 0xffffffff; uint b = a; writefln("%x", a >> 1); writefln("%x", b >> 1); } prints ffffffff 7fffffff
Apr 30 2012
On Sun, Apr 29, 2012 at 02:26:12PM +0200, David Nadlinger wrote: [...]- Comma operator: Kill it with extreme prejudice, it is an anti-feature (allow it in for loop expressions if you really want to, but I think there are better solutions).+1. The voice of reason. [...]- HexString, DelimitedString, r""-WysiwigString, TokenString: I didn't ever use the former two (for including binary data in the program, ImportExpression is imho much easier than generating a source file containing a HexString).I found hexstrings useful for writing unittests for testing Unicode handling (I wanted to test both big- and little-endian UTF-16 and UTF-32, whereas currently string literals can only produce native endian). It might also be useful for unittesting code that takes binary input.As for r"", every time I actually need WysiwigString, I use backticks, because such strings often contain quotes anyway.+1. I think r"" and `` should be merged. Having both is too much.Regarding TokenString(i.e. q{}) – it is certainly a very nice idea, especially regarding syntax highlighting, and I occasionally use them for CTFE code generation.I use tokenstrings a lot for mixins. But arguably that use case would be obsolete when D finally finds a good macro system. [...]- Concatenation of adjacent strings: Also an anti-feature, imho.I personally find them useful for nicely-formatting code that contains lots of long strings. But YMMV.- Floating point comparison operators like !<>= (yes, that _is_ valid D code): I must admit that I seldom write code relying on the finer details of IEEE-754 semantics, but can't they just be »lowered« to a combination of the more common ones?Yeah when I was writing a D lexer (just as an exercise) I was flabbergasted at the sheer amount of comparison operators D has. I mean, I don't know if I will ever use *half* of them in my lifetime. After a while my eyes were just glazing over from all the ASCII UFO's that somehow flew into my code from outer space. If IEEE-754 support is what the intention was, I'd recommend putting them in std.math instead of loading the language with a bunch of apparently-oxymoronic operators like !<> and !<>=, that probably nothing outside of IEEE-754 buffs will ever even care about. [...]- Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs.[...] AA's are moving into druntime. Yours truly is supposed to make that happen eventually, but lately time hasn't been on my side. :-/ This is an interesting idea, though... once we've fully excised AA's from dmd (aside from convenient lowerings from native syntax), it will open up the possibility of writing a GC-less druntime replacement that also provides an alternate implementation of AA's that don't depend on the GC. T -- This is not a sentence.
Apr 29 2012
On Monday, 30 April 2012 at 03:16:09 UTC, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 02:26:12PM +0200, David Nadlinger wrote:This moves the _implementation_ to druntime, but there is still realistically no way to use AA literals with my own non-GC'd version of hash maps without shipping a custom druntime (and thus modifying the semantics of an existing language construct). What I'm talking about would let you do things like MyVector!int stuff = [1, 2, 3, 4, 5]; without needing a (temporary) GC'd allocation, and thus please the GC-hater crowd because they can still have all the syntax candy with their own containers, even if they can't resp. don't want to use the default GC'd constructs. David[…] - Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs.[...] AA's are moving into druntime. Yours truly is supposed to make that happen eventually, but lately time hasn't been on my side. :-/
Apr 29 2012
On Mon, Apr 30, 2012 at 07:07:53AM +0200, David Nadlinger wrote:On Monday, 30 April 2012 at 03:16:09 UTC, H. S. Teoh wrote:[...] I think you're talking about two orthogonal issues here. One is language-level support for arrays and AA's, which IMO are necessary and are even a plus (built-in AA's are one of the big reasons I chose D). The other is language-level support for literal syntax in user-defined types. I think the latter area has lots of room for improvement. From a theoretical standpoint, syntax like [1,2,3,4,5] really should not be prematurely tied to a specific type: at the most fundamental level, it's just specifying a list of things. How the abstract concept of a list of things should be implemented need not be constrained to concrete built-in types; I'd argue that the language should permit the realization of the concept in a user-defined type as well (i.e., the literal interpreted by a user type). Just off the top of my head, this might be achievable by introducing a fromList method in user-defined types that takes a compile-time parameter containing some representation of the list, say as a builtin array. This method then does whatever is needed to create an instance of the type accordingly. (Since the parameter is compile-time, this essentially just generates code to create the custom container directly.) The same thing can be done for custom floating-point literals, say. A fromFloat() method takes a compile-time string containing the literal, and creates an instance of the custom type. (A string is used here so that you can implement types that far exceed the maximum precision of any builtin type.) Ditto for AA literals: a fromAA() method takes a compile-time list of key/value pairs and does whatever it needs to do to create the appropriate runtime AA. In fact, such a construct would alleviate much of the need for compiler hacks to support AA's (both old and the prospective new replacement). There will be no unnecessary overhead of allocating runtime arrays, copying, etc.; the fromAA() method at compile-time generates whatever code is necessary to create the literal into the target object directly. This is a language enhancement issue, though, not really an issue about builtin AA's or arrays being "unnecessary features". T -- All men are mortal. Socrates is mortal. Therefore all men are Socrates.On Sun, Apr 29, 2012 at 02:26:12PM +0200, David Nadlinger wrote:This moves the _implementation_ to druntime, but there is still realistically no way to use AA literals with my own non-GC'd version of hash maps without shipping a custom druntime (and thus modifying the semantics of an existing language construct). What I'm talking about would let you do things like MyVector!int stuff = [1, 2, 3, 4, 5]; without needing a (temporary) GC'd allocation, and thus please the GC-hater crowd because they can still have all the syntax candy with their own containers, even if they can't resp. don't want to use the default GC'd constructs.[…] - Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs.[...] AA's are moving into druntime. Yours truly is supposed to make that happen eventually, but lately time hasn't been on my side. :-/
Apr 29 2012
On 30.04.2012 9:33, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 07:07:53AM +0200, David Nadlinger wrote:*cough* initializer lists *cough* Seriously let AA liters be an sorted initializer list (conceptual compile-time array) of pairs, and normal array literal just plain initializer list of common type. This also nails nicely strange use case of AA literal to build array (just the same sorted table of pairs!). The AA then is just initialized with sorted array at run-time. (as it does anyway) -- Dmitry OlshanskyOn Monday, 30 April 2012 at 03:16:09 UTC, H. S. Teoh wrote:[...] I think you're talking about two orthogonal issues here. One is language-level support for arrays and AA's, which IMO are necessary and are even a plus (built-in AA's are one of the big reasons I chose D). The other is language-level support for literal syntax in user-defined types. I think the latter area has lots of room for improvement. From a theoretical standpoint, syntax like [1,2,3,4,5] really should not be prematurely tied to a specific type: at the most fundamental level, it's just specifying a list of things. How the abstract concept of a list of things should be implemented need not be constrained to concrete built-in types; I'd argue that the language should permit the realization of the concept in a user-defined type as well (i.e., the literal interpreted by a user type). Just off the top of my head, this might be achievable by introducing a fromList method in user-defined types that takes a compile-time parameter containing some representation of the list, say as a builtin array. This method then does whatever is needed to create an instance of the type accordingly. (Since the parameter is compile-time, this essentially just generates code to create the custom container directly.) The same thing can be done for custom floating-point literals, say. A fromFloat() method takes a compile-time string containing the literal, and creates an instance of the custom type. (A string is used here so that you can implement types that far exceed the maximum precision of any builtin type.) Ditto for AA literals: a fromAA() method takes a compile-time list of key/value pairs and does whatever it needs to do to create the appropriate runtime AA. In fact, such a construct would alleviate much of the need for compiler hacks to support AA's (both old and the prospective new replacement). There will be no unnecessary overhead of allocating runtime arrays, copying, etc.; the fromAA() method at compile-time generates whatever code is necessary to create the literal into the target object directly. This is a language enhancement issue, though, not really an issue about builtin AA's or arrays being "unnecessary features".On Sun, Apr 29, 2012 at 02:26:12PM +0200, David Nadlinger wrote:This moves the _implementation_ to druntime, but there is still realistically no way to use AA literals with my own non-GC'd version of hash maps without shipping a custom druntime (and thus modifying the semantics of an existing language construct). What I'm talking about would let you do things like MyVector!int stuff = [1, 2, 3, 4, 5]; without needing a (temporary) GC'd allocation, and thus please the GC-hater crowd because they can still have all the syntax candy with their own containers, even if they can't resp. don't want to use the default GC'd constructs.[…] - Built-in arrays and AAs: They are convenient to use, but as far as I can see the single biggest GC dependency in the language. Why not lower array and AA literals to expression tuples (or whatever) to make the convenient syntax usable with custom (possibly non-GC safe) containers as well? A GC'd default implementation could then be provided in druntime, just like today's arrays and AAs.[...] AA's are moving into druntime. Yours truly is supposed to make that happen eventually, but lately time hasn't been on my side. :-/
Apr 30 2012
On Mon, Apr 30, 2012 at 11:46:09AM +0400, Dmitry Olshansky wrote:On 30.04.2012 9:33, H. S. Teoh wrote:[...][...]I think the latter area has lots of room for improvement. From a theoretical standpoint, syntax like [1,2,3,4,5] really should not be prematurely tied to a specific type: at the most fundamental level, it's just specifying a list of things. How the abstract concept of a list of things should be implemented need not be constrained to concrete built-in types; I'd argue that the language should permit the realization of the concept in a user-defined type as well (i.e., the literal interpreted by a user type). Just off the top of my head, this might be achievable by introducing a fromList method in user-defined types that takes a compile-time parameter containing some representation of the list, say as a builtin array. This method then does whatever is needed to create an instance of the type accordingly. (Since the parameter is compile-time, this essentially just generates code to create the custom container directly.)*cough* initializer lists *cough* Seriously let AA liters be an sorted initializer list (conceptual compile-time array) of pairs, and normal array literal just plain initializer list of common type. This also nails nicely strange use case of AA literal to build array (just the same sorted table of pairs!). The AA then is just initialized with sorted array at run-time. (as it does anyway)[...] +1, this is an excellent idea! It also solves the case of byte[], uint[], int[], etc., all being initializable by "[1,2,3]". Currently, subtle bugs are introduced in certain contexts by the compiler interpreting [1,2,3] to be int[] by default. What we really should do is to pass it in as a compile-time initializer list to the relevant ctors. So byte[].this() will interpret [1,2,3] as bytes, uint[].this() will interpret it as uints, etc.. Then you can write: uint[] a = [ 2: 100, 10: 200 ] and it will be equivalent to: uint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200]; T -- The most powerful one-line C program: #include "/dev/tty" -- IOCCC
Apr 30 2012
On 4/30/12, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:Then you can write: uint[] a = [ 2: 100, 10: 200 ] and it will be equivalent to: uint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200];But you can already use this syntax right now?
Apr 30 2012
Andrej Mitrovic:But there is a syntax problem: http://d.puremagic.com/issues/show_bug.cgi?id=4703 Bye, bearophileuint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200];But you can already use this syntax right now?
Apr 30 2012
On Mon, Apr 30, 2012 at 09:06:06PM +0200, Andrej Mitrovic wrote:On 4/30/12, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:Yes I know you can, it was more of using this syntax for user-defined types without allocating a temporary array. T -- Computers shouldn't beep through the keyhole.Then you can write: uint[] a = [ 2: 100, 10: 200 ] and it will be equivalent to: uint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200];But you can already use this syntax right now?
Apr 30 2012
On 30.04.2012 23:14, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 09:06:06PM +0200, Andrej Mitrovic wrote:Yes I tried to point out that this also makes this code straight forward. AND allows other AA-like enitites to benefit from it. Most importantly it doesn't break a thing. Just generalizes. -- Dmitry OlshanskyOn 4/30/12, H. S. Teoh<hsteoh quickfur.ath.cx> wrote:Yes I know you can, it was more of using this syntax for user-defined types without allocating a temporary array.Then you can write: uint[] a = [ 2: 100, 10: 200 ] and it will be equivalent to: uint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200];But you can already use this syntax right now?
Apr 30 2012
On 4/29/2012 5:26 AM, David Nadlinger wrote:- Anonymous nested classes: They might be useful in Java, particularly in older incarnations, but not so much in D – never used them.I don't like them, either, but they were put in at the recommendation of people who were porting large piles of Java code to D. It made semi-mechanical translation much more feasible. Using them for any other purpose is likely a bad idea, as the only reason they exist in Java is as a kludge to work around limitations in Java.
Apr 30 2012
On 2012-04-28 20:47, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?* Some of the built-in properties could probably be move to a library solution, specially now when we have UFCS. * The with-statement isn't particular useful. Although I've started to use it in one of my projects just so I don't have to use fully qualified enum names. * D embedded in HTML (don't know if this is still supported) * Multiple syntax for wysiwyg strings. I think the r"" syntax can be remove. * Do-while loops, how useful are those actually? Then I think some features could be replaced with library solutions if D got some other features. For example: * foreach(_reverse) * synchronized These could probably be removed in favor of library solutions. void foreach (T)(T[] arr, void delegate (ref T) dg) { for (size_t i = 0; i < arr.length; i++) dg(arr[i]); } foreach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); } The above syntax would be very useful in other cases as well. The same could be done for "synchronized" as well. Might even be possible to remove the for-statement and just have "while" left. I we want get even more wild and crazy I think Scala's solution for operator overloading looks really good. But that would require several other features to work. Like: * Everything is an object (might not be needed with UFCS) * Everything is a method call on an object * Infix notation for calling any method taking one argument * Basically any symbol is allowed in method names That is: 1 + 2 foo bar foo_bar Would be translated to: 1.+(2) foo.bar(foo_bar) That is a very general way to handle operators and let the user create new operators, not just overloading existing ones. -- /Jacob Carlborg
Apr 29 2012
On 29.04.2012 18:40, Jacob Carlborg wrote:1 + 2 foo bar foo_bar Would be translated to: 1.+(2) foo.bar(foo_bar) That is a very general way to handle operators and let the user create new operators, not just overloading existing ones.warning(1): Smalltalk detected! [use -foop-only to ignore] Operator precedence would get real tricky (or stupid just like in Smalltalk). -- Dmitry Olshansky
Apr 29 2012
On Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:foreach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); }We'd still need a solution for continue and break, though. David
Apr 29 2012
On 2012-04-29 17:07, David Nadlinger wrote:On Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:This has already been solved when using opApply, although quite an ugly solution. -- /Jacob Carlborgforeach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); }We'd still need a solution for continue and break, though. David
Apr 29 2012
On Sunday, 29 April 2012 at 16:10:40 UTC, Jacob Carlborg wrote:On 2012-04-29 17:07, David Nadlinger wrote:Yes, but that requires the compiler to generate the return value »glue« code for continue/break inside an opApply foreach. If foreach is a library function and you pass an ordinary delegate, you have a problem in the current language since you can't know that a »return« statement inside that delegate really should return from the outer function. DavidOn Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:This has already been solved when using opApply, although quite an ugly solution.foreach ([1, 2, 3, 4] ; i) { writeln(i); }We'd still need a solution for continue and break, though. David
Apr 29 2012
On 2012-04-29 19:03, David Nadlinger wrote:Yes, but that requires the compiler to generate the return value »glue« code for continue/break inside an opApply foreach. If foreach is a library function and you pass an ordinary delegate, you have a problem in the current language since you can't know that a »return« statement inside that delegate really should return from the outer function. DavidYeah, that would need to be solved. In Ruby it works like this: [1, 2, 3, 4].each do |i| if i == 2 return end end Results in: LocalJumpError: unexpected return If you instead wrap it in method you can return from the each-block. So in Ruby it behaves just like having a "return" in a plain for-loop and not in a delegate. It would basically force a return in the "each" method. -- /Jacob Carlborg
Apr 29 2012
On Sunday, 29 April 2012 at 15:07:26 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:A thought coming to mind regarding this, is a special exception. If the compiler recognizes it's part of a foreach (or other loop) then continue gets converted to return, and and break throws an exception (caught by the foreach of course) But that involves more compiler magic.foreach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); }We'd still need a solution for continue and break, though.
Apr 29 2012
On 30-04-2012 01:54, Era Scarecrow wrote:On Sunday, 29 April 2012 at 15:07:26 UTC, David Nadlinger wrote:And forced EH which is unacceptable in e.g. a kernel. -- - AlexOn Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:A thought coming to mind regarding this, is a special exception. If the compiler recognizes it's part of a foreach (or other loop) then continue gets converted to return, and and break throws an exception (caught by the foreach of course) But that involves more compiler magic.foreach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); }We'd still need a solution for continue and break, though.
Apr 29 2012
On Mon, Apr 30, 2012 at 01:57:58AM +0200, Alex Rønne Petersen wrote:On 30-04-2012 01:54, Era Scarecrow wrote:[...]On Sunday, 29 April 2012 at 15:07:26 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:[...] Here's a wild idea: introduce the concept of the multi-return function (or, in this case, delegate). Unlike normal functions which returns to a single point when they end, usually by pushing the return address onto the runtime stack, a multi-return function is called by pushing _multiple_ return addresses onto the runtime stack. The function body decides which return address to use (it can only use one of them). Implementing break/continue then can be done like this: the loop body delegate will be a multi-return delegate, i.e., a delegate whose caller will provide multiple return addresses: one for each possible break/continue point. For example: outerLoop: foreach (a; containerA) { innerLoop: foreach (b; containerB) { if (condition1()) continue outerLoop; if (condition2()) break /* innerLoop */; if (condition3()) break outerLoop; } if (condition4()) break /* outerLoop */; } When containerA.opApply is called, it calls the outer loop body with two return addresses: the first is the usual return address from a function call, the second is the cleanup code at the end of opApply that performs any necessary cleanups and then returns. I.e., it simulates break. So when condition4 triggers, the outerLoop delegate returns to the second address. Now the outerLoop delegate itself calls containerB.opApply with a list of outer loop return addresses, i.e., (1) return to containerA.opApply's caller, that is, break outerLoop, (2) return to outerLoop delegate's cleanup code, i.e. continue OuterLoop. Then containerB.opApply prepends two more return addresses to this list, the usual return address to containerB.opApply, and its corresponding break return (prepend because the last return addressed pushed must correspond with the immediate containing scope of the called delegate, but if the delegate knows about outer scopes then it can return to those). Now the innerLoop delegate has four return addresses: return to containerB.opApply normally (continue innerLoop), return to containerB.opApply's cleanup code (break innerLoop), return to containerA.opApply normally (continue outerLoop), and return to containerA.opApply's cleanup code (break outerLoop). So break/continue works for all cases. (Of course, containerB.opApply doesn't actually just prepend return addresses to what the outerLoop delegate passes in, since when the innerLoop delegate wants to break outerLoop, it needs to cleanup the stack frames of the intervening call to containerB.opApply too. So containerB.opApply needs to insert its own cleanup code into the return address chain.) This is, at least, the *conceptual* aspect of things. In the actual implementation, the compiler may use the current scheme (return an int to indicate which return is desired) instead of doing what amounts to reinventing stack unwinding, but the important point is, this should be transparent to user code. As far as the user is concerned, they just call the delegate normally, no need to check return codes, etc., with the understanding that the said delegates have multiple return addresses. The compiler inserts the necessary scaffolding, checking for int returns, etc., to actually implement the concept. T -- WINDOWS = Will Install Needless Data On Whole System -- CompuManAnd forced EH which is unacceptable in e.g. a kernel.We'd still need a solution for continue and break, though.A thought coming to mind regarding this, is a special exception. If the compiler recognizes it's part of a foreach (or other loop) then continue gets converted to return, and and break throws an exception (caught by the foreach of course) But that involves more compiler magic.
Apr 29 2012
Le 30/04/2012 06:20, H. S. Teoh a écrit :On Mon, Apr 30, 2012 at 01:57:58AM +0200, Alex Rønne Petersen wrote:This make sense. This seems to me like the way to go.On 30-04-2012 01:54, Era Scarecrow wrote:[...]On Sunday, 29 April 2012 at 15:07:26 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 14:40:38 UTC, Jacob Carlborg wrote:[...] Here's a wild idea: introduce the concept of the multi-return function (or, in this case, delegate). Unlike normal functions which returns to a single point when they end, usually by pushing the return address onto the runtime stack, a multi-return function is called by pushing _multiple_ return addresses onto the runtime stack. The function body decides which return address to use (it can only use one of them). Implementing break/continue then can be done like this: the loop body delegate will be a multi-return delegate, i.e., a delegate whose caller will provide multiple return addresses: one for each possible break/continue point. For example: outerLoop: foreach (a; containerA) { innerLoop: foreach (b; containerB) { if (condition1()) continue outerLoop; if (condition2()) break /* innerLoop */; if (condition3()) break outerLoop; } if (condition4()) break /* outerLoop */; } When containerA.opApply is called, it calls the outer loop body with two return addresses: the first is the usual return address from a function call, the second is the cleanup code at the end of opApply that performs any necessary cleanups and then returns. I.e., it simulates break. So when condition4 triggers, the outerLoop delegate returns to the second address. Now the outerLoop delegate itself calls containerB.opApply with a list of outer loop return addresses, i.e., (1) return to containerA.opApply's caller, that is, break outerLoop, (2) return to outerLoop delegate's cleanup code, i.e. continue OuterLoop. Then containerB.opApply prepends two more return addresses to this list, the usual return address to containerB.opApply, and its corresponding break return (prepend because the last return addressed pushed must correspond with the immediate containing scope of the called delegate, but if the delegate knows about outer scopes then it can return to those). Now the innerLoop delegate has four return addresses: return to containerB.opApply normally (continue innerLoop), return to containerB.opApply's cleanup code (break innerLoop), return to containerA.opApply normally (continue outerLoop), and return to containerA.opApply's cleanup code (break outerLoop). So break/continue works for all cases. (Of course, containerB.opApply doesn't actually just prepend return addresses to what the outerLoop delegate passes in, since when the innerLoop delegate wants to break outerLoop, it needs to cleanup the stack frames of the intervening call to containerB.opApply too. So containerB.opApply needs to insert its own cleanup code into the return address chain.) This is, at least, the *conceptual* aspect of things. In the actual implementation, the compiler may use the current scheme (return an int to indicate which return is desired) instead of doing what amounts to reinventing stack unwinding, but the important point is, this should be transparent to user code. As far as the user is concerned, they just call the delegate normally, no need to check return codes, etc., with the understanding that the said delegates have multiple return addresses. The compiler inserts the necessary scaffolding, checking for int returns, etc., to actually implement the concept.And forced EH which is unacceptable in e.g. a kernel.We'd still need a solution for continue and break, though.A thought coming to mind regarding this, is a special exception. If the compiler recognizes it's part of a foreach (or other loop) then continue gets converted to return, and and break throws an exception (caught by the foreach of course) But that involves more compiler magic.
Apr 30 2012
On 29-04-2012 16:40, Jacob Carlborg wrote:On 2012-04-28 20:47, Walter Bright wrote:+1.Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?* Some of the built-in properties could probably be move to a library solution, specially now when we have UFCS.* The with-statement isn't particular useful. Although I've started to use it in one of my projects just so I don't have to use fully qualified enum names.It is very useful in some cases where you operate a lot on the same object.* D embedded in HTML (don't know if this is still supported)Madness... I think it's deprecated now.* Multiple syntax for wysiwyg strings. I think the r"" syntax can be remove. * Do-while loops, how useful are those actually?I use them occasionally, but it's certainly true that they are rarely useful.Then I think some features could be replaced with library solutions if D got some other features. For example: * foreach(_reverse) * synchronized These could probably be removed in favor of library solutions. void foreach (T)(T[] arr, void delegate (ref T) dg) { for (size_t i = 0; i < arr.length; i++) dg(arr[i]); } foreach ([1, 2, 3, 4], (i) { writeln(i); }); The above already works today. If we can a bit syntax sugar for delegates and inlinable delegates we could have this: foreach ([1, 2, 3, 4] ; i) { writeln(i); } The above syntax would be very useful in other cases as well. The same could be done for "synchronized" as well. Might even be possible to remove the for-statement and just have "while" left. I we want get even more wild and crazy I think Scala's solution for operator overloading looks really good. But that would require several other features to work. Like: * Everything is an object (might not be needed with UFCS) * Everything is a method call on an object * Infix notation for calling any method taking one argument * Basically any symbol is allowed in method names That is: 1 + 2 foo bar foo_bar Would be translated to: 1.+(2) foo.bar(foo_bar) That is a very general way to handle operators and let the user create new operators, not just overloading existing ones.-- - Alex
Apr 29 2012
On Sun, Apr 29, 2012 at 04:40:37PM +0200, Jacob Carlborg wrote: [...]* Do-while loops, how useful are those actually?OK, that got me all riled up about looping constructs, and now I'm provoked to rant: Since the advent of structured programming, looping constructs have always been somewhat b0rken. Yes they worked very well, they are clean, powerful, gets rid of almost all cases of needing goto's, etc.. But the point of a loop is that *the entry point does not always correspond with the exit point (where the loop condition is tested)*. The problem with both do-loops and while-loops is that they are just straitjacketed versions of a more general looping construct. At its most fundamental level, a loop consists of an entry point, a loop body, and some point within the loop body where the loop exits. Sometimes you need multiple exits, but most cases only need a single exit point. So a loop (unrolled) might look like this: codeBeforeLoop(); // Loop body begins here doSomething(); if (!loopCondition) goto exitLoop; doSomethingElse(); doSomething(); if (!loopCondition) goto exitLoop; doSomethingElse(); ... exitLoop: codeAfterLoop(); Note that I deliberately split the loop body into two parts, before the loop condition and after the loop condition. This is because you often have code like this: auto line = nextLine(); while (!eof()) { processLine(line); line = nextLine(); } Notice the duplicated nextLine() call. That's stupid, the initial call to nextLine() is actually already the beginning of the loop. Why do you need to repeat it again inside the loop? Because while-loops always tests the loop condition at the beginning of the loop. OK, what about using a do-loop instead? do { auto line = nextLine(); if (!eof()) processLine(line); } while (!eof()); OK, we got rid of the duplicated nextLine() call, but now we introduced a duplicated eof() test. This is also stupid. The only reason it has to be written in this stupid way is because do-loops always test the loop condition at the end of the loop body, but you need to evaluate the condition BEFORE the second half of the loop body (processLine) is run. But once you've evaluated that condition, the test at the end of the loop body is redundant. So you might say, OK, just write this then: for(;;) { auto line = nextLine(); if (eof()) break; processLine(line); } Well, finally you have something sane. The loop condition now correctly appears in the middle of the loop body, which is where it should've been all along. Only problem is, writing for(;;) is misleading, because you're not looping indefinitely, there's precisely one exit condition. Conveying intent is very important in writing good code, and this code breaks that principle. So really, what is needed is a sane looping construct that unifies while loops, do-loops, and exit-in-the-middle loops. Something like this: loop { // first part of loop body } exitWhen(!loopCondition) { // second part of loop body } It doesn't have to be this exact syntax, but the point is that you need to be able to express loop exits from the middle of a loop body without needing to resort to for(;;) and break, when the loop is a good ole simple loop with a single entry point and a single exit point. (More complex loops that need continue's and break's are, well, more complex, so it's OK to sprinkle if conditions in them like we do now.) </rant> [...]* Infix notation for calling any method taking one argument * Basically any symbol is allowed in method names That is: 1 + 2 foo bar foo_bar Would be translated to: 1.+(2) foo.bar(foo_bar) That is a very general way to handle operators and let the user create new operators, not just overloading existing ones.[...] While personally, I like the idea of being able to create new infix operators, it will cause too big a change to D syntax, and probably cause lots of breakages with existing code, as well as make the lexer/parser much harder to implement (given the existing D features). You also then have to deal with operator precedence between arbitrary user-defined operators, which is non-trivial in general (though it's workable if you impose some constrains -- but it's probably way beyond the scope of D2 or even D3). T -- Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
Apr 29 2012
On 30/04/12 05:45, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 04:40:37PM +0200, Jacob Carlborg wrote: [...]I grepped through the DMD source once, looking for how often Walter uses do..while. The answer: exactly zero.* Do-while loops, how useful are those actually?OK, that got me all riled up about looping constructs, and now I'm provoked to rant: Since the advent of structured programming, looping constructs have always been somewhat b0rken. Yes they worked very well, they are clean, powerful, gets rid of almost all cases of needing goto's, etc.. But the point of a loop is that *the entry point does not always correspond with the exit point (where the loop condition is tested)*. The problem with both do-loops and while-loops is that they are just straitjacketed versions of a more general looping construct.Completely agree. Forth is one of the few languages which got it right. BEGIN .... cond WHILE ... REPEAT
Apr 30 2012
Don Clugston:In my code I use one do-while about every 20 or 30 loops, so they aren't very common, but are useful. If I need a random 2D point on a disk, one method to produce it is by rejection, I use a do-while loop, I extract two coordinates in a square, and then test if they are inside the disk, otherwise I loop. But I have a problem with D-style do-while loops, that some time ago I have discussed a bit in D.learn: I can't use them like this, because the variables defined inside the loop are not visible in the loop test: do { // ... const x = compute something } while (predicate(x)); I have to use this, that is less handy: T x; do { // ... x = compute something } while (predicate(x)); Bye, bearophileI grepped through the DMD source once, looking for how often Walter uses do..while. The answer: exactly zero.* Do-while loops, how useful are those actually?
Apr 30 2012
On 30.04.2012 7:45, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 04:40:37PM +0200, Jacob Carlborg wrote:[snip]So you might say, OK, just write this then: for(;;) { auto line = nextLine(); if (eof()) break; processLine(line); } Well, finally you have something sane. The loop condition now correctly appears in the middle of the loop body, which is where it should've been all along. Only problem is, writing for(;;) is misleading, because you're not looping indefinitely, there's precisely one exit condition. Conveying intent is very important in writing good code, and this code breaks that principle. So really, what is needed is a sane looping construct that unifies while loops, do-loops, and exit-in-the-middle loops. Something like this: loop { // first part of loop body } exitWhen(!loopCondition) { // second part of loop body }You'd love PL/SQL. :) -- Dmitry Olshansky
Apr 30 2012
On 2012-04-30 05:45, H. S. Teoh wrote:While personally, I like the idea of being able to create new infix operators, it will cause too big a change to D syntax, and probably cause lots of breakages with existing code, as well as make the lexer/parser much harder to implement (given the existing D features). You also then have to deal with operator precedence between arbitrary user-defined operators, which is non-trivial in general (though it's workable if you impose some constrains -- but it's probably way beyond the scope of D2 or even D3).Yes, a language would basically need to be designed with this in mind from the start. That's what I'm thing sometimes, D could have gone down some other road in some cases but it's way too late to change it now. -- /Jacob Carlborg
Apr 30 2012
On 04/30/2012 05:45 AM, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 04:40:37PM +0200, Jacob Carlborg wrote: [...] So really, what is needed is a sane looping construct that unifies while loops, do-loops, and exit-in-the-middle loops. Something like this: loop { // first part of loop body } exitWhen(!loopCondition) { // second part of loop body } It doesn't have to be this exact syntax, but the point is that you need to be able to express loop exits from the middle of a loop body without needing to resort to for(;;) and break, when the loop is a good ole simple loop with a single entry point and a single exit point. (More complex loops that need continue's and break's are, well, more complex, so it's OK to sprinkle if conditions in them like we do now.) </rant>do{ // ... }while(cond){ // ... } I think the scoping rules of the do-while loop should be fixed such that the loop condition can refer to loop-local variables. Violates C backwards compatibility though...[...]Should be trivial. (The parser can just defer operator precedence resolution to the analysis phase if necessary, and otherwise it is very simple anyway.)* Infix notation for calling any method taking one argument * Basically any symbol is allowed in method names That is: 1 + 2 foo bar foo_bar Would be translated to: 1.+(2) foo.bar(foo_bar) That is a very general way to handle operators and let the user create new operators, not just overloading existing ones.[...] While personally, I like the idea of being able to create new infix operators, it will cause too big a change to D syntax, and probably cause lots of breakages with existing code, as well as make the lexer/parser much harder to implement (given the existing D features).You also then have to deal with operator precedence between arbitrary user-defined operators, which is non-trivial in general (though it's workable if you impose some constrainsI kinda like the Scala-approach.-- but it's probably way beyond the scope of D2 or even D3).An issue is that it clashes with eg. a+***ptrtoptrtoptrtodata.
Apr 30 2012
On 28.04.2012 20:47, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?* The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift). * package. I have no idea how a failed Java experiment got incorporated into D. * the zoo of parameter passing options * Most of the __traits are useless and redundant.
Apr 29 2012
On Sunday, 29 April 2012 at 15:50:54 UTC, Don wrote:* package. I have no idea how a failed Java experiment got incorporated into D.+1, forgot to mention that one. David
Apr 29 2012
On Sunday, 29 April 2012 at 17:05:19 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 15:50:54 UTC, Don wrote:What's wrong with packages ?* package. I have no idea how a failed Java experiment got incorporated into D.+1, forgot to mention that one. David
Apr 29 2012
On Sunday, 29 April 2012 at 18:39:49 UTC, SomeDude wrote:What's wrong with packages ?Nothing – this is about the »package« protection level, not packages. ;) David
Apr 29 2012
On Sunday, 29 April 2012 at 18:47:11 UTC, David Nadlinger wrote:On Sunday, 29 April 2012 at 18:39:49 UTC, SomeDude wrote:Ah ok. But I'm not sure what's wrong with the package protection level either, actually.What's wrong with packages ?Nothing – this is about the »package« protection level, not packages. ;) David
Apr 29 2012
On 29-04-2012 22:24, SomeDude wrote:On Sunday, 29 April 2012 at 18:47:11 UTC, David Nadlinger wrote:Yes, me neither. And I have found many cases in my code where using it actually makes sense and helps encapsulation. -- - AlexOn Sunday, 29 April 2012 at 18:39:49 UTC, SomeDude wrote:Ah ok. But I'm not sure what's wrong with the package protection level either, actually.What's wrong with packages ?Nothing – this is about the »package« protection level, not packages. ;) David
Apr 29 2012
On Sunday, 29 April 2012 at 21:06:10 UTC, Alex Rønne Petersen wrote:On 29-04-2012 22:24, SomeDude wrote:See the Java discussion on »superpackages« – quite often, you want to share stuff in mylibrary.subpackage with the rest of mylibrary, but not the world. DavidAh ok. But I'm not sure what's wrong with the package protection level either, actually.Yes, me neither. And I have found many cases in my code where using it actually makes sense and helps encapsulation.
Apr 29 2012
Don:* package. I have no idea how a failed Java experiment got incorporated into D.Weren't Java designers thinking about adding superpackages too to Java?* the zoo of parameter passing optionsPlease explain, what do you mean? Bye, bearophile
Apr 29 2012
On 29 April 2012 18:50, Don <nospam nospam.com> wrote:On 28.04.2012 20:47, Walter Bright wrote:What does it do? I use this all over the place, I assumed it worked... maybe I have bugs?Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?* The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift).* package. I have no idea how a failed Java experiment got incorporated into D.package confuses me, it's poorly documented. What are the protections between packages, sub-packages. Can parent packages see sub-package contents? vice-versa? * Most of the __traits are useless and redundant.Which traits are useless and redundant? I'm actually finding the set is incomplete, and there are some missing (parameter list introspection, current scope/object identification, current module/package)
Apr 29 2012
On 04/29/2012 08:08 PM, Manu wrote:On 29 April 2012 18:50, Don <nospam nospam.com <mailto:nospam nospam.com>> wrote: On 28.04.2012 20:47, Walter Bright wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? * The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift). What does it do? I use this all over the place, I assumed it worked... maybe I have bugs?It does work, but it behaves in unexpected ways for narrow signed integers (short/byte) because it sign-extends them before shifting. It works fine with int/uint/long/ulong.* Most of the __traits are useless and redundant. Which traits are useless and redundant? I'm actually finding the set is incomplete, and there are some missing (parameter list introspection, current scope/object identification, current module/package)+1.
Apr 29 2012
Am 29.04.2012 20:08, schrieb Manu:On 29 April 2012 18:50, Don <nospam nospam.com [...] * package. I have no idea how a failed Java experiment got incorporated into D. package confuses me, it's poorly documented. What are the protections between packages, sub-packages. Can parent packages see sub-package contents? vice-versa?I've always assume that package is similar to what is available in another module based languages. Where you have a library (package) that is composed of several separated modules. In certain scenarios, you want to have symbols that are private to the library, but need to be marked public so that each module, that is part of the library, is able to see them. So you mark those symbols as package level access. This is usually done in "programming in the large" projects. Some examples where I think this concept might be visible, - .NET Modules (internal is used for visibility accross .dll) - default package access for Java common namespaces scattered across several jar files - Ada limited and child packages - Delphi packages -- Paulo
Apr 29 2012
On 29/04/2012 19:08, Manu wrote:current module/packagehttp://dlang.org/phobos/std_traits#packageName http://dlang.org/phobos/std_traits#moduleName -- Robert http://octarineparrot.com/
Apr 29 2012
On 2012-04-29 20:08, Manu wrote:package confuses me, it's poorly documented. What are the protections between packages, sub-packages. Can parent packages see sub-package contents? vice-versa?As far as I know it works like this: pack |- pack1 |- foo.d |- bar.d |- pack2 |- a.d |- pack3 |- b.d |- c.d // pack.pack1.foo package int x = 3; // pack.pack1.bar x = 4; // this is fine since it's in the same package. // pack.pack1.pack2.a x = 5; // error, cannot access package protected variable. // pack.pack3.b x = 6; // error, cannot access package protected variable. // pack.c x = 7; // error, cannot access package protected variable. Oh, and "package" is non-virtual, for some reason. -- /Jacob Carlborg
Apr 29 2012
On 29/04/12 20:08, Manu wrote:On 29 April 2012 18:50, Don <nospam nospam.com <mailto:nospam nospam.com>> wrote: On 28.04.2012 20:47, Walter Bright wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? * The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift). What does it do? I use this all over the place, I assumed it worked... maybe I have bugs?It works only for two types: int and long. For everything else, it is identical to >> So for short and byte, and in generic code, it's ALWAYS a bug.
Apr 30 2012
On 30 April 2012 10:32, Don Clugston <dac nospam.com> wrote:On 29/04/12 20:08, Manu wrote:O_O Is that intentional? Or is it... a bug? I smiled when I saw >>> in the language, I appreciate its presence. It's not necessary, but it cuts down on some ugly explicit casting (which theoretically makes generic code simpler).On 29 April 2012 18:50, Don <nospam nospam.com <mailto:nospam nospam.com>> wrote: On 28.04.2012 20:47, Walter Bright wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? * The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift). What does it do? I use this all over the place, I assumed it worked... maybe I have bugs?It works only for two types: int and long. For everything else, it is identical to >> So for short and byte, and in generic code, it's ALWAYS a bug.
Apr 30 2012
On 30/04/12 12:27, Manu wrote:On 30 April 2012 10:32, Don Clugston <dac nospam.com <mailto:dac nospam.com>> wrote: On 29/04/12 20:08, Manu wrote: On 29 April 2012 18:50, Don <nospam nospam.com <mailto:nospam nospam.com> <mailto:nospam nospam.com <mailto:nospam nospam.com>>> wrote: On 28.04.2012 20:47, Walter Bright wrote: Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list? * The >>> operator, which does nothing except introduce bugs (It does NOT perform an unsigned shift). What does it do? I use this all over the place, I assumed it worked... maybe I have bugs? It works only for two types: int and long. For everything else, it is identical to >> So for short and byte, and in generic code, it's ALWAYS a bug. O_O Is that intentional? Or is it... a bug? I smiled when I saw >>> in the language, I appreciate its presence. It's not necessary, but it cuts down on some ugly explicit casting (which theoretically makes generic code simpler).It's not a bug, it's a design flaw. The buggy behaviour is explicitly tested in the test suite. The problem is that the C promotion rules also apply, just as for >> and <<. But they are fundamentally incompatible with unsigned shift. So short and byte get promoted to int *by sign extension*, then the int gets an unsigned shift. Which means that the short or byte gets a signed shift instead of an unsigned one. I used to use >>> in my code, because as you say, it is a nice idea, but after having a few bugs with short, and working out what the semantics actually were, I suddenly realized it was a landmine, and I removed every instance of it from my code. (cast(ulong)x) >> 3 is safer than x >>> 3, unfortunately.
Apr 30 2012
Le 30/04/2012 14:44, Don Clugston a écrit :It's not a bug, it's a design flaw. The buggy behaviour is explicitly tested in the test suite. The problem is that the C promotion rules also apply, just as for >> and <<. But they are fundamentally incompatible with unsigned shift. So short and byte get promoted to int *by sign extension*, then the int gets an unsigned shift. Which means that the short or byte gets a signed shift instead of an unsigned one.Thanks for pointing that out. Sadly, it makes some sense with the C integer promotion rules.
May 01 2012
On 04/30/2012 02:44 PM, Don Clugston wrote:(cast(ulong)x) >> 3 is safer than x >>> 3, unfortunately.In what way is it safer? void main() { short x = -1; assert((cast(ulong)x) >> 3 == cast(long)x >>> 3); }
May 01 2012
On Sunday, April 29, 2012 17:50:48 Don wrote:* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API. - Jonathan M Davis
Apr 29 2012
On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:On Sunday, April 29, 2012 17:50:48 Don wrote:It's entirely dependent on your coding style. For example, when you look at Phobos you rarely (if ever?) see package functions. This is because it's entirely module based with a strong degree of separation between modules. awful. I personally use package quite often. For the most part, I stick to one major class per file, and separate things across library. There are plenty of things that I want other classes in the package/static-library to use, but don't want to expose to the public, and thus use package for.* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API. - Jonathan M Davis
Apr 29 2012
On Monday, April 30, 2012 05:12:27 Kapps wrote:On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:It's a question of how inter-dependent your modules are (which is partly a question of style). If you have a bunch of closely related functionality that should be in separate modules, then it can be quite easy for it to need have stuff which it needs to share but shouldn't be public. This happens much more easily if you follow a style of putting one class per module as you _must_ do Phobos doesn't have all that many types in it (though that's changing as it grows). Historically, it's been (and mostly still is) a collection of free functions which have been organized in modules with related functions sharing modules. However, free functions tend to be quite independent. At most, they may share some private helpers. They rarely need to share stuff across modules. On top of that, Phobos has historically avoided creating sub-modules in favor of a flat hierarchy (though that's starting to change) The result of this is that package hasn't been needed in Phobos. I suspect that Don's take on things comes from that (and he probably hasn't needed package in his own stuff either). But I don't think that it's very hard at all to come up with examples where package level access can be invaluable. - Jonathan M DavisOn Sunday, April 29, 2012 17:50:48 Don wrote:It's entirely dependent on your coding style. For example, when you look at Phobos you rarely (if ever?) see package functions. This is because it's entirely module based with a strong degree of separation between modules. awful. I personally use package quite often. For the most part, I stick to one major class per file, and separate things across library. There are plenty of things that I want other classes in the package/static-library to use, but don't want to expose to the public, and thus use package for.* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API. - Jonathan M Davis
Apr 29 2012
Le 30/04/2012 05:12, Kapps a écrit :On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:Phobos is a really good example. Modules tend to become more and more fat. And to split them up, package is mandatory.On Sunday, April 29, 2012 17:50:48 Don wrote:It's entirely dependent on your coding style. For example, when you look at Phobos you rarely (if ever?) see package functions. This is because it's entirely module based with a strong degree of separation between modules. personally use package quite often. For the most part, I stick to one major class per file, and separate things across library. There are plenty of things that I want other classes in the package/static-library to use, but don't want to expose to the public, and thus use package for.* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API. - Jonathan M Davis
Apr 30 2012
On Monday, 30 April 2012 at 12:35:24 UTC, deadalnix wrote:Phobos is a really good example. Modules tend to become more and more fat. And to split them up, package is mandatory.Except that it doesn't work if the module you want to refactor into a sub-package already used »package«… David
Apr 30 2012
On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:On Sunday, April 29, 2012 17:50:48 Don wrote:But what happens if std.datetime grows so large that you want to have e.g. a std.datetime.system package, the content of which is accessible from std.datetime.*, but not the rest of the world? This is not an artificial problem, e.g. consider Thrift, where I have e.g. thrift.internal.endian (predating endian stuff in Phobos) which is used from modules in thrift.async, thrift.server, and thrift.protocol, or thrift.internal.socket (containing some more OS abstractions than std.socket does), which is used from modules in thrift.async, thrift.server, and thrift.transport, but both are not part of the public API. The logical »package« to restrict access to would be »thrift.*« here, but there is no way to restrict access to that, I have to resort to hoping users understand that they should not use »thrift.internal.xyz« directly. Phobos has the same problem with std.internal. I think in Java this problem was the reason for »super packages« to be discussed which (I think, haven't followed it the developments closely) ended up being incorporated in the upcoming Module System feature. David* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API.
Apr 29 2012
On Monday, April 30, 2012 06:58:18 David Nadlinger wrote:On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:heOn Sunday, April 29, 2012 17:50:48 Don wrote:=20 But what happens if std.datetime grows so large that you want to have e.g. a std.datetime.system package, the content of which is accessible from std.datetime.*, but not the rest of the world? =20 This is not an artificial problem, e.g. consider Thrift, where I have e.g. thrift.internal.endian (predating endian stuff in Phobos) which is used from modules in thrift.async, thrift.server, and thrift.protocol, or thrift.internal.socket (containing some more OS abstractions than std.socket does), which is used from modules in thrift.async, thrift.server, and thrift.transport, but both are not part of the public API. =20 The logical =C2=BBpackage=C2=AB to restrict access to would be =C2=BBthrift.*=C2=AB here, but there is no way to restrict access to that, I have to resort to hoping users understand that they should not use =C2=BBthrift.internal.xyz=C2=AB directly. Phobos has t=* package. I have no idea how a failed Java experiment got incorporated into D.=20 Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API.same problem with std.internal. =20 I think in Java this problem was the reason for =C2=BBsuper packages=C2=AB to be discussed which (I think, haven't followed it the developments closely) ended up being incorporated in the upcoming Module System feature.I'm not claiming that package solves all such issues (and you do give s= ome=20 good examples where it would be a problem), but not having it would mak= e the=20 problem even worse. I think that this is one area though where the Wind= ows=20 folks take advantage of their export nonsense and just don't export the= =20 internal stuff. - Jonathan M Davis
Apr 29 2012
I don't see export as nonsense. :) "Jonathan M Davis" wrote in message news:mailman.137.1335762449.24740.digitalmars-d puremagic.com... On Monday, April 30, 2012 06:58:18 David Nadlinger wrote:On Monday, 30 April 2012 at 01:08:28 UTC, Jonathan M Davis wrote:I'm not claiming that package solves all such issues (and you do give some good examples where it would be a problem), but not having it would make the problem even worse. I think that this is one area though where the Windows folks take advantage of their export nonsense and just don't export the internal stuff. - Jonathan M DavisOn Sunday, April 29, 2012 17:50:48 Don wrote:But what happens if std.datetime grows so large that you want to have e.g. a std.datetime.system package, the content of which is accessible from std.datetime.*, but not the rest of the world? This is not an artificial problem, e.g. consider Thrift, where I have e.g. thrift.internal.endian (predating endian stuff in Phobos) which is used from modules in thrift.async, thrift.server, and thrift.protocol, or thrift.internal.socket (containing some more OS abstractions than std.socket does), which is used from modules in thrift.async, thrift.server, and thrift.transport, but both are not part of the public API. The logical »package« to restrict access to would be »thrift.*« here, but there is no way to restrict access to that, I have to resort to hoping users understand that they should not use »thrift.internal.xyz« directly. Phobos has the same problem with std.internal. I think in Java this problem was the reason for »super packages« to be discussed which (I think, haven't followed it the developments closely) ended up being incorporated in the upcoming Module System feature.* package. I have no idea how a failed Java experiment got incorporated into D.Really? In some cases, it's indispensable. For instance, once std.datetime has been split up, it will require it, or it would have duplicate a bunch of implementation-specific stuff which has no business in the public API.
Apr 30 2012
Walter:What's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter & Andrei? Bye, bearophile
Apr 29 2012
On Monday, April 30, 2012 01:41:45 bearophile wrote:Walter:Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else. As for TODOs, the impression that I got from Walter's post was that he wanted to know what people thought out of curiosity or just for "lessons learned" from the design process of D and not that he was really looking to remove anything from the language. So, I don't think that it was ever his intention to create a TODO list from this (though I could be wrong). There may be some minor things that get changed (such as making it so that adjacent string literals don't get automatically concatenated), but I don't think that D is really going to have any of its features removed at this point. - Jonathan M DavisWhat's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter & Andrei?
Apr 29 2012
On 30.04.2012 10:55, Jonathan M Davis wrote:On Monday, April 30, 2012 01:41:45 bearophile wrote:foreach_reverse, comma operator, etc.Walter:Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else.What's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter& Andrei?As for TODOs, the impression that I got from Walter's post was that he wanted to know what people thought out of curiosity or just for "lessons learned" from the design process of D and not that he was really looking to remove anything from the language. So, I don't think that it was ever his intention to create a TODO list from this (though I could be wrong). There may be some minor things that get changed (such as making it so that adjacent string literals don't get automatically concatenated), but I don't think that D is really going to have any of its features removed at this point. - Jonathan M Davis-- Dmitry Olshansky
Apr 30 2012
On Monday, 30 April 2012 at 07:52:10 UTC, Dmitry Olshansky wrote:On 30.04.2012 10:55, Jonathan M Davis wrote:These are the only two I can count that nobody felt eager to keep. Yet these are only nitpicks. Also, both work, so the benefit of removing them vs breaking code... I would be glad to remove the current comma operator if its semantic was changed for something like this: http://forum.dlang.org/post/ajdmseliewbindkkoxxj forum.dlang.org But I don't think it's on the table. So I believe the conclusion several of us have reached is, that it's more important to make things that already exist work as intended without ugly corner cases and hacks.On Monday, April 30, 2012 01:41:45 bearophile wrote:foreach_reverse, comma operator, etc.Walter:Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else.What's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter& Andrei?
Apr 30 2012
Jonathan M Davis:Honestly, I don't think that you _can_ take much from this thread other thanI don't agree, I see some recurring patterns. People have spent energy and time to write lot of answers in this thread, some good answer bits too, so I expect such work to not let be fully wasted. Asking for opinions, receiving lot of them, and then ignoring them all is not a good way to run a community. And thank you for your answer, I always appreciate your answers, but you aren't Walter, that post was for him (and Andrei) to answer :-) Bye, bearophile
Apr 30 2012
On Monday, April 30, 2012 11:15:17 bearophile wrote:Jonathan M Davis:I never claimed that I _was_ Walter. I was pointing out that there's very little consensus in this thread (almost all of the comments are in conflict with other comments) so that even if it was our intention to go and remove things from the language based on this thread, there is very little, if anything, that has a clear consensus on being removed. The closest would probably be the comma operator, and there wasn't even a complete consensus on _that_. And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure. - Jonathan M DavisHonestly, I don't think that you _can_ take much from this thread other thanI don't agree, I see some recurring patterns. People have spent energy and time to write lot of answers in this thread, some good answer bits too, so I expect such work to not let be fully wasted. Asking for opinions, receiving lot of them, and then ignoring them all is not a good way to run a community. And thank you for your answer, I always appreciate your answers, but you aren't Walter, that post was for him (and Andrei) to answer :-)
Apr 30 2012
On 4/30/2012 10:04 AM, Jonathan M Davis wrote:I never claimed that I _was_ Walter. I was pointing out that there's very little consensus in this thread (almost all of the comments are in conflict with other comments) so that even if it was our intention to go and remove things from the language based on this thread, there is very little, if anything, that has a clear consensus on being removed. The closest would probably be the comma operator, and there wasn't even a complete consensus on _that_.There is less agreement than I thought there would be. This thread also generated far more interest than I anticipated.And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure.The first thing to emphasize is that NONE of this will happen for D2. The emphasis on D2 is fixing implementation and toolchain issues. Breaking existing code is off the table unless we are pretty much forced to in order to fix some other more important issue. So we're talking several years out. The evolution of C++ is interesting. So far, the C++ committee has shown incredible resistance to removing, or even deprecating, some features that pretty much everyone knows were a mistake, all in the interests of maintaining backwards compatibility. Some of C++'s success can be attributed to that, but also some of its endemic failures. Where's the line to draw between breaking existing code and modernizing / removing cruft / removing support for features that promote bad code? Of course, there can't be any fixed rule for that. Hearing peoples' opinions on it on a case by case basis helps a lot. We've had some success in deprecating mistaken features - the bit data type, and typedefs. I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.
Apr 30 2012
On Monday, 30 April 2012 at 19:50:36 UTC, Walter Bright wrote:I'm surprised nobody has mentioned opApply.opApply is great. I find myself finding new, kinda crazy things to do with it every so often, like concurrency sugar.
Apr 30 2012
On 30-04-2012 21:50, Walter Bright wrote:On 4/30/2012 10:04 AM, Jonathan M Davis wrote:I think what we need is an article on ranges on dlang.org (I can't find one). They seem like a rather foreign concept when you come from other languages, like array slices, and need a proper introduction. -- - AlexI never claimed that I _was_ Walter. I was pointing out that there's very little consensus in this thread (almost all of the comments are in conflict with other comments) so that even if it was our intention to go and remove things from the language based on this thread, there is very little, if anything, that has a clear consensus on being removed. The closest would probably be the comma operator, and there wasn't even a complete consensus on _that_.There is less agreement than I thought there would be. This thread also generated far more interest than I anticipated.And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure.The first thing to emphasize is that NONE of this will happen for D2. The emphasis on D2 is fixing implementation and toolchain issues. Breaking existing code is off the table unless we are pretty much forced to in order to fix some other more important issue. So we're talking several years out. The evolution of C++ is interesting. So far, the C++ committee has shown incredible resistance to removing, or even deprecating, some features that pretty much everyone knows were a mistake, all in the interests of maintaining backwards compatibility. Some of C++'s success can be attributed to that, but also some of its endemic failures. Where's the line to draw between breaking existing code and modernizing / removing cruft / removing support for features that promote bad code? Of course, there can't be any fixed rule for that. Hearing peoples' opinions on it on a case by case basis helps a lot. We've had some success in deprecating mistaken features - the bit data type, and typedefs. I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.
Apr 30 2012
On Monday, 30 April 2012 at 19:58:49 UTC, Alex Rønne Petersen wrote:On 30-04-2012 21:50, Walter Bright wrote: I think what we need is an article on ranges on dlang.org (I can't find one). They seem like a rather foreign concept when you come from other languages, like array slices, and need a proper introduction.There is one talk by Andrei http://blip.tv/boostcon/boostcon-2009-keynote-2452140 and there is the chapter on Ali's book: http://ddili.org/ders/d.en/ranges.html
Apr 30 2012
On 30-04-2012 22:25, SomeDude wrote:On Monday, 30 April 2012 at 19:58:49 UTC, Alex Rønne Petersen wrote:Right, but we can't expect people who want to learn the language and its conventions to have to go to some external source for information. It has to be on dlang.org. -- - AlexOn 30-04-2012 21:50, Walter Bright wrote: I think what we need is an article on ranges on dlang.org (I can't find one). They seem like a rather foreign concept when you come from other languages, like array slices, and need a proper introduction.There is one talk by Andrei http://blip.tv/boostcon/boostcon-2009-keynote-2452140 and there is the chapter on Ali's book: http://ddili.org/ders/d.en/ranges.html
Apr 30 2012
On Monday, 30 April 2012 at 20:28:56 UTC, Alex Rønne Petersen wrote:On 30-04-2012 22:25, SomeDude wrote:I've put these links in the Wiki. They may not be visible enough, though. It still needs a lot of cleanup (although I've done a little bit of it). Baically, the first one is in the tutorials. The second is in "Why switch ?"On Monday, 30 April 2012 at 19:58:49 UTC, Alex Rønne Petersen wrote:Right, but we can't expect people who want to learn the language and its conventions to have to go to some external source for information. It has to be on dlang.org.On 30-04-2012 21:50, Walter Bright wrote: I think what we need is an article on ranges on dlang.org (I can't find one). They seem like a rather foreign concept when you come from other languages, like array slices, and need a proper introduction.There is one talk by Andrei http://blip.tv/boostcon/boostcon-2009-keynote-2452140 and there is the chapter on Ali's book: http://ddili.org/ders/d.en/ranges.html
Apr 30 2012
On 04/30/2012 09:50 PM, Walter Bright wrote:I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.foreach has been mentioned. I don't think ranges are unequivocally a superior solution. opApply is more powerful for fancy iteration tasks, such as parallel foreach.
Apr 30 2012
On Monday, 30 April 2012 at 20:04:41 UTC, Timon Gehr wrote:On 04/30/2012 09:50 PM, Walter Bright wrote:Yes, I feel they are complementary. Ranges are cool for Python-style or functional-style programming, foreach and opApply reflects more traditional iteration. I'm pretty sure that usage over time will show that they both have their use.I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.foreach has been mentioned. I don't think ranges are unequivocally a superior solution. opApply is more powerful for fancy iteration tasks, such as parallel foreach.
Apr 30 2012
On Mon, 30 Apr 2012 15:50:00 -0400, Walter Bright <newshound2 digitalmars.com> wrote:I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.I think we've already covered this -- opApply does things that ranges could never do. I think they can both live in harmony. It's not even close to a dead end. I look at opApply as foreach on a range with a stack-allocated context specifically for iteration. Then of course, you can do stack-based traversal, which is not really possible for ranges. A trivial example: foreach(dchar d; "longstring") {} treating "longstring" as a range, you cannot possibly get the performance opApply has (although, you have to be able to inline both the opApply call and the delegate calls, currently not supported for the above code), as it has to decode each dchar *twice*, once for getting d, and once for popping it off the front. -Steve
Apr 30 2012
On 4/30/2012 1:33 PM, Steven Schveighoffer wrote:I think we've already covered this -- opApply does things that ranges could never do.deprecating opApply would require addressing this.
Apr 30 2012
Walter:The first thing to emphasize is that NONE of this will happen for D2. The emphasis on D2 is fixing implementation and toolchain issues. Breaking existing code is off the table unless we are pretty much forced to in order to fix some other more important issue.But you need to keep into account that D2 is still a not widely used language. So deprecating some things now will cause far less troubles than doing it in D3 some years from now. So I suggest to be a bit more flexible on this.We've had some success in deprecating mistaken features - the bit data type, and typedefs.In the end I agree that deprecating typedef was the right thing. Not because it's useless, quite the contrary, but because it was not well designed, so it's better to remove it to have a chance later to get it more right. Adding if far simpler than removing. But keep in mind that Phobos Typedef is so broken that it's essentially not usable in practical situations (quite more broken even than emplace and rebindable, that have several problems). So we don't have a replacement yet. Bye, bearophile
Apr 30 2012
On 04/30/2012 11:28 PM, bearophile wrote:Walter:D2 -> D3 will be full of breaking changes anyway. Otherwise there is no reason to add another major language version.The first thing to emphasize is that NONE of this will happen for D2. The emphasis on D2 is fixing implementation and toolchain issues. Breaking existing code is off the table unless we are pretty much forced to in order to fix some other more important issue.But you need to keep into account that D2 is still a not widely used language. So deprecating some things now will cause far less troubles than doing it in D3 some years from now.
Apr 30 2012
On 5/1/12, Timon Gehr <timon.gehr gmx.ch> wrote:D2 -> D3 will be full of breaking changes anyway.Uhmm I hope not, otherwise D3 will be dead in the water.
Apr 30 2012
On 05/01/2012 12:53 AM, Andrej Mitrovic wrote:On 5/1/12, Timon Gehr<timon.gehr gmx.ch> wrote:Then what is the point of D3?D2 -> D3 will be full of breaking changes anyway.Uhmm I hope not,otherwise D3 will be dead in the water.Just provide an automatic D2->D3 conversion facility.
Apr 30 2012
On 5/1/12, Timon Gehr <timon.gehr gmx.ch> wrote:On 05/01/2012 12:53 AM, Andrej Mitrovic wrote:An incremental improvement with as little code breakage as possible? You can't even properly mix D1 and D2 code in the same library right now without resorting to using mixin() tricks.On 5/1/12, Timon Gehr<timon.gehr gmx.ch> wrote:Then what is the point of D3?D2 -> D3 will be full of breaking changes anyway.Uhmm I hope not,
Apr 30 2012
On 05/01/2012 01:30 AM, Andrej Mitrovic wrote:On 5/1/12, Timon Gehr<timon.gehr gmx.ch> wrote:IMHO that is similar to aiming for some code breakage with as little improvement as possible. Retainment of backwards-compatibility is what makes languages convoluted. Furthermore, the translation from D2->D3 should be possible to be performed automatically.On 05/01/2012 12:53 AM, Andrej Mitrovic wrote:An incremental improvement with as little code breakage as possible?On 5/1/12, Timon Gehr<timon.gehr gmx.ch> wrote:Then what is the point of D3?D2 -> D3 will be full of breaking changes anyway.Uhmm I hope not,You can't even properly mix D1 and D2 code in the same library right nowwithout resorting to using mixin() tricks.This means you actually can!
Apr 30 2012
On Tuesday, May 01, 2012 01:30:11 Andrej Mitrovic wrote:On 5/1/12, Timon Gehr <timon.gehr gmx.ch> wrote:But you could do that without creating a D3. Once the implemnetation has stabilized, it should be possible to add new features to D2 as long as they're backwards compatible (e.g. adding user-defined attributes). The only reason to create D3 would be if we wanted to make changes which _weren't_ backwards compatible. - Jonathan M DavisOn 05/01/2012 12:53 AM, Andrej Mitrovic wrote:An incremental improvement with as little code breakage as possible? You can't even properly mix D1 and D2 code in the same library right now without resorting to using mixin() tricks.On 5/1/12, Timon Gehr<timon.gehr gmx.ch> wrote:Then what is the point of D3?D2 -> D3 will be full of breaking changes anyway.Uhmm I hope not,
Apr 30 2012
Timon Gehr:D2 -> D3 will be full of breaking changes anyway. Otherwise there is no reason to add another major language version.I remember Walter (and Andrei) stated that D2 is the latest major breaking change in D. So D3 is supposed to be a smooth change (but of course no one knows what will happen). Bye, bearophile
Apr 30 2012
On 01/05/12 00:33, Timon Gehr wrote:On 04/30/2012 11:28 PM, bearophile wrote:What is this D3 thing ???? As far as I can tell, 'D3' was invented by newcomers to the forums.Walter:D2 -> D3 will be full of breaking changes anyway. Otherwise there is no reason to add another major language version.The first thing to emphasize is that NONE of this will happen for D2. The emphasis on D2 is fixing implementation and toolchain issues. Breaking existing code is off the table unless we are pretty much forced to in order to fix some other more important issue.But you need to keep into account that D2 is still a not widely used language. So deprecating some things now will cause far less troubles than doing it in D3 some years from now.
May 03 2012
On Thursday, May 03, 2012 15:30:40 Don Clugston wrote:What is this D3 thing ???? As far as I can tell, 'D3' was invented by newcomers to the forums.I think that what it comes down to is that there are a variety of people who want features added or changed in D which are either not going to happen anytime soon or will never happen in D2 (especially if they're major breaking changes). So, they figure/hope that we'll have a new revision of the language where we'll be able to make breaking changes and then maybe the changes that they want will make it in then. After all, particularly from the perspective of a newbie, we already had D2 which changed a bunch of stuff from D1, why wouldn't we have D3 later on? And for folks who really want to see changes that aren't going to happen, the idea that we're going to have another major revision of the language which might make the changes that they want sounds really appealing. I think that Walter and Andrei have made it fairly clear when they've said anything on the subject that there is no intention to make any kind of D3 anytime soon and that if we do, it'll be years from now after D2 is mature and well-established, and it actually makes sense to do a new major revision. But I do think that you're right in that the very idea of a D3 was created by folks in the newsgroup. Walter and the other developers have been focusing on stabilizing D2 as _the_ version of the language, not finishing it up so that they can move onto D3. And the misconceptions about D1 that you've pointed out in the past probably just help contribute to the idea that we'll have a D3 at some point. Maybe we will, maybe we won't, but there's no point in worrying about it for years yet. - Jonathan M Davis
May 03 2012
On Thursday, 3 May 2012 at 20:36:47 UTC, Jonathan M Davis wrote:On Thursday, May 03, 2012 15:30:40 Don Clugston wrote:If anything, I would consider D3 an ideal, something to work towards. And no it wouldn't be started or really worked on for at 10-15 years after D's mature and at Andrei's goal of having at least a million users. And as stated before, if there [b]IS[/b] going to be a D3 at any point it should have no problem calling D2 code. Course thinking of D3 now is kinda like thinking of flying cars and how you want a flying car and you won't buy a car today until it can fly... Back (in the 50-60's was it?) they thought we would be having a flying car for every family and had these really badly done animations of what they expected to see. I don't see any flying cars outside of Hollywood. Best if we stick in the present and deal with our problems now.What is this D3 thing ???? As far as I can tell, 'D3' was invented by newcomers to the forums.I think that what it comes down to is that there are a variety of people who want features added or changed in D which are either not going to happen anytime soon or will never happen in D2 (especially if they're major breaking changes). So, they figure/hope that we'll have a new revision of the language where we'll be able to make breaking changes and then maybe the changes that they want will make it in then. After all, particularly from the perspective of a newbie, we already had D2 which changed a bunch of stuff from D1, why wouldn't we have D3 later on? And for folks who really want to see changes that aren't going to happen, the idea that we're going to have another major revision of the language which might make the changes that they want sounds really appealing. I think that Walter and Andrei have made it fairly clear when they've said anything on the subject that there is no intention to make any kind of D3 anytime soon and that if we do, it'll be years from now after D2 is mature and well-established, and it actually makes sense to do a new major revision. But I do think that you're right in that the very idea of a D3 was created by folks in the newsgroup. Walter and the other developers have been focusing on stabilizing D2 as _the_ version of the language, not finishing it up so that they can move onto D3. And the misconceptions about D1 that you've pointed out in the past probably just help contribute to the idea that we'll have a D3 at some point. Maybe we will, maybe we won't, but there's no point in worrying about it for years yet.
May 03 2012
On Thu, May 03, 2012 at 11:32:52PM +0200, Era Scarecrow wrote: [[...]If anything, I would consider D3 an ideal, something to work towards. And no it wouldn't be started or really worked on for at 10-15 years after D's mature and at Andrei's goal of having at least a million users. And as stated before, if there [b]IS[/b] going to be a D3 at any point it should have no problem calling D2 code.Do we know (roughly) how many D users are out there right now?Course thinking of D3 now is kinda like thinking of flying cars and how you want a flying car and you won't buy a car today until it can fly... Back (in the 50-60's was it?) they thought we would be having a flying car for every family and had these really badly done animations of what they expected to see. I don't see any flying cars outside of Hollywood. Best if we stick in the present and deal with our problems now.There aren't any flying cars in Hollywood either. They're either just artist's concepts (*cough*CGI models*cough*), held up by strings, or just superimposed on an animated background. T -- It is not the employer who pays the wages. Employers only handle the money. It is the customer who pays the wages. -- Henry Ford
May 03 2012
On Thursday, 3 May 2012 at 22:29:47 UTC, H. S. Teoh wrote:On Thu, May 03, 2012 at 11:32:52PM +0200, Era Scarecrow wrote: Do we know (roughly) how many D users are out there right now?Don't know. Need a poll :) I'm definitely sure we have at least 10 users; beyond that I can only speculate; Maybe 2 to the power of ten or thirteen...There aren't any flying cars in Hollywood either. They're either just artist's concepts (*cough*CGI models*cough*), held up by strings, or just superimposed on an animated background.Exactly! It's on the 'big screen', meaning smoke and gimmicks, the same as magicians. Anyways, focus on the now. D3 may/will come some day, but that's a long ways off. Course if you plan early for certain things that will change it does make going towards it easier with language design, or give you more time to think about faults and fixes.
May 03 2012
On Fri, May 04, 2012 at 01:12:20AM +0200, Era Scarecrow wrote:On Thursday, 3 May 2012 at 22:29:47 UTC, H. S. Teoh wrote:Only 10?? Judging from mailing list membership, I'd say at least 25 or 30, just on the forums alone. I'm assuming that people here aren't subscribed just for kicks, they actually write D code. There are probably more outside the forums (somebody mentioned an entire company of D programmers before, perhaps about 50-100? I don't remember the exact figure). There's got to be more out there, given that Andrei has been giving talks about D for a while. *Somebody* in the audience must be actually listening to what he says. But in any case, I'd say we have a ways to go yet in terms of D adoption. [...]On Thu, May 03, 2012 at 11:32:52PM +0200, Era Scarecrow wrote: Do we know (roughly) how many D users are out there right now?Don't know. Need a poll :) I'm definitely sure we have at least 10 users; beyond that I can only speculate; Maybe 2 to the power of ten or thirteen...Anyways, focus on the now. D3 may/will come some day, but that's a long ways off. Course if you plan early for certain things that will change it does make going towards it easier with language design, or give you more time to think about faults and fixes.Yep. T -- Those who don't understand Unix are condemned to reinvent it, poorly.
May 03 2012
On Thursday, 3 May 2012 at 23:40:32 UTC, H. S. Teoh wrote:Only 10?? Judging from mailing list membership, I'd say at least 25 or 30, just on the forums alone. I'm assuming that people here aren't subscribed just for kicks, they actually write D code. There are probably more outside the forums (somebody mentioned an entire company of D programmers before, perhaps about 50-100? I don't remember the exact figure). There's got to be more out there, given that Andrei has been giving talks about D for a while. *Somebody* in the audience must be actually listening to what he says.I was being sarcastic :P
May 03 2012
On 04-05-2012 01:41, H. S. Teoh wrote:On Fri, May 04, 2012 at 01:12:20AM +0200, Era Scarecrow wrote:There are more users than one might think. If you fancy some IRC, you should drop by #d (104 users), #d.gdc (17 users), #ldc (18 users), #d.sdc (5 users) on irc.freenode.net. :) There's also #d on irc.oftc.net (started by Iain).On Thursday, 3 May 2012 at 22:29:47 UTC, H. S. Teoh wrote:Only 10?? Judging from mailing list membership, I'd say at least 25 or 30, just on the forums alone. I'm assuming that people here aren't subscribed just for kicks, they actually write D code. There are probably more outside the forums (somebody mentioned an entire company of D programmers before, perhaps about 50-100? I don't remember the exact figure). There's got to be more out there, given that Andrei has been giving talks about D for a while. *Somebody* in the audience must be actually listening to what he says. But in any case, I'd say we have a ways to go yet in terms of D adoption.On Thu, May 03, 2012 at 11:32:52PM +0200, Era Scarecrow wrote: Do we know (roughly) how many D users are out there right now?Don't know. Need a poll :) I'm definitely sure we have at least 10 users; beyond that I can only speculate; Maybe 2 to the power of ten or thirteen...[...]-- - AlexAnyways, focus on the now. D3 may/will come some day, but that's a long ways off. Course if you plan early for certain things that will change it does make going towards it easier with language design, or give you more time to think about faults and fixes.Yep. T
May 03 2012
On 2012-05-03 22:36, Jonathan M Davis wrote:On Thursday, May 03, 2012 15:30:40 Don Clugston wrote:People has been talking about D3 for quite a while. Have a look at: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel Search for "Known to be deferred to D3.0". The features listed there were talked about before D2. -- /Jacob CarlborgWhat is this D3 thing ???? As far as I can tell, 'D3' was invented by newcomers to the forums.I think that what it comes down to is that there are a variety of people who want features added or changed in D which are either not going to happen anytime soon or will never happen in D2 (especially if they're major breaking changes). So, they figure/hope that we'll have a new revision of the language where we'll be able to make breaking changes and then maybe the changes that they want will make it in then. After all, particularly from the perspective of a newbie, we already had D2 which changed a bunch of stuff from D1, why wouldn't we have D3 later on? And for folks who really want to see changes that aren't going to happen, the idea that we're going to have another major revision of the language which might make the changes that they want sounds really appealing. I think that Walter and Andrei have made it fairly clear when they've said anything on the subject that there is no intention to make any kind of D3 anytime soon and that if we do, it'll be years from now after D2 is mature and well-established, and it actually makes sense to do a new major revision. But I do think that you're right in that the very idea of a D3 was created by folks in the newsgroup. Walter and the other developers have been focusing on stabilizing D2 as _the_ version of the language, not finishing it up so that they can move onto D3. And the misconceptions about D1 that you've pointed out in the past probably just help contribute to the idea that we'll have a D3 at some point. Maybe we will, maybe we won't, but there's no point in worrying about it for years yet. - Jonathan M Davis
May 04 2012
On Friday, May 04, 2012 09:38:24 Jacob Carlborg wrote:On 2012-05-03 22:36, Jonathan M Davis wrote:Oh. I know that they've been talking about it for a while, but as far as I can tell, the term has gotten used primarily due to people who don't like the fact that D2 is doing something a particular way or isn't doing something a particular way and who hope that there will be a future version of the language which does it the way that they want. Certainly, it's not something which Walter has pushed at all (the opposite, if anything). - Jonathan M DavisOn Thursday, May 03, 2012 15:30:40 Don Clugston wrote:People has been talking about D3 for quite a while. Have a look at: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel Search for "Known to be deferred to D3.0". The features listed there were talked about before D2.What is this D3 thing ???? As far as I can tell, 'D3' was invented by newcomers to the forums.I think that what it comes down to is that there are a variety of people who want features added or changed in D which are either not going to happen anytime soon or will never happen in D2 (especially if they're major breaking changes). So, they figure/hope that we'll have a new revision of the language where we'll be able to make breaking changes and then maybe the changes that they want will make it in then. After all, particularly from the perspective of a newbie, we already had D2 which changed a bunch of stuff from D1, why wouldn't we have D3 later on? And for folks who really want to see changes that aren't going to happen, the idea that we're going to have another major revision of the language which might make the changes that they want sounds really appealing. I think that Walter and Andrei have made it fairly clear when they've said anything on the subject that there is no intention to make any kind of D3 anytime soon and that if we do, it'll be years from now after D2 is mature and well-established, and it actually makes sense to do a new major revision. But I do think that you're right in that the very idea of a D3 was created by folks in the newsgroup. Walter and the other developers have been focusing on stabilizing D2 as _the_ version of the language, not finishing it up so that they can move onto D3. And the misconceptions about D1 that you've pointed out in the past probably just help contribute to the idea that we'll have a D3 at some point. Maybe we will, maybe we won't, but there's no point in worrying about it for years yet. - Jonathan M Davis
May 04 2012
Walter:The evolution of C++ is interesting.I think the evolution and updating patterns of the language Scale are more interesting for us. Bye, bearophile
Apr 30 2012
On Monday, 30 April 2012 at 19:50:36 UTC, Walter Bright wrote: [...]I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.Both internal and external iteration have their pros and cons. It doesn't make sense to claim one is superior to the other. Ranges are more appropriate for serial code whereas internal iteration is better suited for concurrent code.
Apr 30 2012
On Monday, 30 April 2012 at 19:50:36 UTC, Walter Bright wrote:I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.I practically never use ranges, and instead use opApply for all my code. 1) Ranges force me to use a specific naming convention. My naming convention that I use for my projects is upper camel case. Ranges do not allow this. Technically opApply is still lower camel case, but my code doesn't directly call it. 2) Ranges don't have a way of determining when the iteration ends. Sometimes you want to do something once iteration stops. For example, by far the most common action when executing a database call for me, is to iterate over it and close it. I can then have a helper method that executes the command and closes it when the foreach is done (whether by break or by the function ending). This saves quite a bit of boiler plate code. 3) Ranges can be difficult to implement. You now have to keep track of state instead of simply leaving everything inside a single method call. This can also cause significant problems with multi-threaded code. 4) Ranges take a lot more code, which when all you want is basic iteration, is pointless to have. I'd much rather just see things with opApply being able to have a forward-range magically created for it, much like the reverse. Not sure if this is possible or practical though.
Apr 30 2012
Sorry for my 2nd intervention on this thread. I recently ported some (not much) code from C to D. My impression was that D(2) tries to be too many things at once. I even considered porting to D(1) instead of D(2). What attracted me into the first place to D was it promise to be a "better C" (and a better C++), at least this is I saw it. However, it seems to have grown too complex to me. Yes, I understand that new, modern features should be provided by the language, but I do not like to be forced to use those. From my (limited) background, what I really liked in D: *the new type[n] and type* declaration syntax *the templates syntax (that's a biiig plus) *other things that I do not remember now, but they are plenty of them *the fact that constructors and destructors do not need renaming when class name changes (I hated that in C++ and Java), although I would have liked more special kewords like "ctor()" and "dtor()", instead of "this()" and "~this()", but I can cope with that) What I did NOT like in D (is my impression): *the confusion between . and -> operators (yes, I know the latter does not exist in D, is just for talking first here) for classes and structs and why classes are or are not pointers and why structs behave differently (or, at least, this is how I perceive it) and why not the pointer syntax is not used if they are pointers (well, references) and so on (yes, I am a bit dizzy, but is not entirely my fault; it's also D's). *the many annotations that is not clear if they are compulsory or not (and, if not, how to convince me to use them...) *the writing of the p[0..len] that you need to use when some other code (C code) passes you the pointer to data and the length (I just do not like it) *it is also my impression that you cannot declare int[] x=<<some_initialization>> as a static array with length filled in by compiler at the compile time, since the length is known? instead, x is interpreted as a dynamic array (which, also, I do not like that same syntax, or very similar, is used for both concepts). *the fact that the calling of a function bears no indication if you modify or not the passed variable (I much prefer the C-ish style of foo(a,&b); where you *almost* know that b will be modified) Well, these are some. I feel that the right line is somewhere between D1 and D2. It is good that advanced, complex features are present in D, I just not want to be forced to use those when porting "traditional" C code. I expected to meet D and exclaim: wow! C++ done right! Instead, I feel like being forced to learn another, completely new paradigm language, like I would start with Lisp or something else. Remember: "Within D, there is a much smaller and cleaner language struggling to get out".
Apr 30 2012
akaz:Well, these are some. I feel that the right line is somewhere between D1 and D2. It is good that advanced, complex features are present in D, I just not want to be forced to use those when porting "traditional" C code. I expected to meet D and exclaim: wow! C++ done right! Instead, I feel like being forced to learn another, completely new paradigm language, like I would start with Lisp or something else.I think D is not C++ done right any more, it's a new language. This was probably necessary if you want D to have a more than minimal chance of success. I have translated a significant amount of C code to D1 and D2, and usually in such simple porting I find bugs in the original C code, like off-by-on errors in arrays, missing returns, missing breaks in switches, dead code paths caused by precedent returns, erroneous re-uses of loop variables used in outer scopes, and so on. So I love such (moderate) bug-discovering qualities of D, and I'd like D to have even more of them. In many cases D doesn't force you to use its advanced features, it allows you to write very C-looking code too (that is usually bad D code). But probably D can't allow this in every case, some things need to change if you want to improve the language a little. So think of those forced uses as a small price to pay to have a better language. Bye, bearophile
Apr 30 2012
On 05/01/2012 01:20 AM, akaz wrote:I expected to meet D and exclaim: wow! C++ done right! Instead, I feel like being forced to learn another,Yes, D is its own thing.completely new paradigm language, like I would start with Lisp or something else.OTOH, this seems to be an exaggeration.Remember: "Within D, there is a much smaller and cleaner language struggling to get out".I don't see the value of that assertion from a pragmatic point of view. What is to be gained? Note that you have discussed mostly syntax. * adding -> does not make the language smaller or cleaner and it complicates generic code for no benefit. * loosening the syntactic distinction between value and reference type variable declarations could be done, (to the neat effect that tail-qualified class references would trivially work) but there shouldn't be any directly built-in support for treating polymorphic class instances as values. * I agree that the property situation needs to be cleaned up. There are only five annotations in total. And what you have said does not apply to the other four. * how p[0..len] can be seen as an issue instead of as great completely escapes my mind. * I agree on supporting deducing length for static arrays. (there is a int[$] arr = [1,2,3]; proposal.) * the syntax for arrays is straightforward and I don't see any potential for improvement. * the foo(a,&b) example is biased because it uses a meaningless function name. From the function name alone it is often *almost* clear that a certain argument will be modified. & & & spam is not 'clean' either.
Apr 30 2012
Timon Gehr:* I agree on supporting deducing length for static arrays. (there is a int[$] arr = [1,2,3]; proposal.)Someone in Bugzilla ha just proposed an alternative idea, that despite not looking very nice, is not overall bad (here with a small change): auto arr = [1, 2, 3]f; That trailing f denotes a fixed-side array/string literal. So it's usable for other situations too.* the foo(a,&b) example is biased because it uses a meaningless function name. From the function name alone it is often *almost* clear that a certain argument will be modified. & & & spam is not 'clean' either.most cases). D language has chosen a different design, but here bit more clear. Bye, bearophile
Apr 30 2012
On Tue, May 01, 2012 at 02:14:42AM +0200, bearophile wrote:Timon Gehr:[...] I don't like it. An f prefix already means float in another context; overloading it to also mean static array is a bad idea. D already has too much overloaded syntax (like static meaning all sorts of diverse things depending on context). I much prefer the int[$] proposal, because $ already means "length of array" in D, and so would fit right in. T -- We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true. -- Robert Wilensk* I agree on supporting deducing length for static arrays. (there is a int[$] arr = [1,2,3]; proposal.)Someone in Bugzilla ha just proposed an alternative idea, that despite not looking very nice, is not overall bad (here with a small change): auto arr = [1, 2, 3]f; That trailing f denotes a fixed-side array/string literal. So it's usable for other situations too.
Apr 30 2012
On 01-05-2012 02:14, bearophile wrote:Timon Gehr:Tell me about it... I've had a few WTF and WAT moments due to D's design here.* I agree on supporting deducing length for static arrays. (there is a int[$] arr = [1,2,3]; proposal.)Someone in Bugzilla ha just proposed an alternative idea, that despite not looking very nice, is not overall bad (here with a small change): auto arr = [1, 2, 3]f; That trailing f denotes a fixed-side array/string literal. So it's usable for other situations too.* the foo(a,&b) example is biased because it uses a meaningless function name. From the function name alone it is often *almost* clear that a certain argument will be modified. & & & spam is not 'clean' either.some advantages too, it makes the code semantics a bit more clear.Bye, bearophile-- - Alex
Apr 30 2012
On 05/01/12 02:25, H. S. Teoh wrote:On Tue, May 01, 2012 at 02:14:42AM +0200, bearophile wrote:Since one of the most characteristic D features is overloading "static" whenever possible, this would fit right in: auto arr = static [1, 2, 3]; arturTimon Gehr:[...] I don't like it. An f prefix already means float in another context; overloading it to also mean static array is a bad idea. D already has too much overloaded syntax (like static meaning all sorts of diverse things depending on context). I much prefer the int[$] proposal, because $ already means "length of array" in D, and so would fit right in.* I agree on supporting deducing length for static arrays. (there is a int[$] arr = [1,2,3]; proposal.)Someone in Bugzilla ha just proposed an alternative idea, that despite not looking very nice, is not overall bad (here with a small change): auto arr = [1, 2, 3]f; That trailing f denotes a fixed-side array/string literal. So it's usable for other situations too.
May 01 2012
On 2012-05-01 11:50, Artur Skawina wrote:Since one of the most characteristic D features is overloading "static" whenever possible, this would fit right in: auto arr = static [1, 2, 3]; arturMeaning this would need to be allowed: static arr = static [1, 2, 3]; That looks a bit confusing. -- /Jacob Carlborg
May 01 2012
On Tuesday, 1 May 2012 at 00:02:37 UTC, Timon Gehr wrote:* how p[0..len] can be seen as an issue instead of as great completely escapes my mind.I can only offer my own experiences. When I first saw D1 and saw ranges used like that, it looked like pure greek and confused the hell out of me. I mean, what is this ..? How does it work? Only after a lightbulb appearing over my head did I realize .. was just another operator, which didn't exist in C or C++. Having the example completely broken down into equiv D code that doesn't use the .. makes it's use and glue to the compiler a bit more obvious and fills in the gaps. I mean, how would you take a foreign symbols of << 1->End >> to be? If you squint, it's just a slightly different syntax for the same thing; depending on how you interpret the languages(s).
Apr 30 2012
On Tue, 01 May 2012 01:20:53 +0200, akaz <nemo utopia.com> wrote:*the confusion between . and -> operators (yes, I know the latter does not exist in D, is just for talking first here) for classes and structs and why classes are or are not pointers and why structs behave differently (or, at least, this is how I perceive it) and why not the pointer syntax is not used if they are pointers (well, references) and so on (yes, I am a bit dizzy, but is not entirely my fault; it's also D's).Really? This is one of the big pluses to me.*the writing of the p[0..len] that you need to use when some other code (C code) passes you the pointer to data and the length (I just do not like it)While I can agree it's not perfect, I have a hard time seeing a better solution. Somewhere the information has to be combined to create a proper array.*it is also my impression that you cannot declare int[] x=<<some_initialization>> as a static array with length filled in by compiler at the compile time, since the length is known? instead, x is interpreted as a dynamic array (which, also, I do not like that same syntax, or very similar, is used for both concepts).Agreed.*the fact that the calling of a function bears no indication if you modify or not the passed variable (I much prefer the C-ish style of foo(a,&b); where you *almost* know that b will be modified)parameters ref or out. I'd really like that for D too.
Apr 30 2012
On 05/01/2012 12:54 AM, Kapps wrote:On Monday, 30 April 2012 at 19:50:36 UTC, Walter Bright wrote:Yes they do. (If you are willing to have both kinds of symbols around.) mixin template AddAliasesForBuiltInRange(){ alias Front front; alias Empty empty; alias PopFront popFront; } struct R{ ... property Front(){...} property bool Empty(){...} void PopFront(){...} mixin AddAliasesForBuiltInRange; }I'm surprised nobody has mentioned opApply. That was a good idea at the time, but Ranges are a superior solution. I'd like to see new code not use opApply. It's a dead end, though it'll still be supported for a long time.I practically never use ranges, and instead use opApply for all my code. 1) Ranges force me to use a specific naming convention. My naming convention that I use for my projects is upper camel case. Ranges do not allow this.Technically opApply is still lower camel case, but my code doesn't directly call it.The same would hold for the above example.2) Ranges don't have a way of determining when the iteration ends. Sometimes you want to do something once iteration stops. For example, by far the most common action when executing a database call for me, is to iterate over it and close it. I can then have a helper method that executes the command and closes it when the foreach is done (whether by break or by the function ending). This saves quite a bit of boiler plate code.An important point.3) Ranges can be difficult to implement. You now have to keep track of state instead of simply leaving everything inside a single method call. This can also cause significant problems with multi-threaded code. 4) Ranges take a lot more code, which when all you want is basic iteration, is pointless to haveThose two could be mitigated by moving the range concept further into the language.I'd much rather just see things with opApply being able to have a forward-range magically created for it, much like the reverse. Not sure if this is possible or practical though.Am implementation (that is possible now) could use coroutines (core.thread.Fiber), but that is not very efficient for simple return. (In D the compiler would generate anonymous struct types instead of IEnumerable interface implementations).
Apr 30 2012
Kapps:1) Ranges force me to use a specific naming convention. My naming convention that I use for my projects is upper camel case. Ranges do not allow this.Not following the common naming conventions of a language is bad, or quite bad. Most or all modern languages seem to have realized When I see D code written by other people it's very handy to guess some characteristics of the things I'm using assuming it follows the D common naming conventions. This makes reading code simpler, faster, reduces some chances of introducing bugs, and makes is quicker to hack into code written by other people. Bye, bearophile
Apr 30 2012
On Mon, Apr 30, 2012 at 01:04:01PM -0400, Jonathan M Davis wrote: [...]And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure.[...] It would be unwise to make major changes to the language at this point. Personally I'd like to see the comma operator removed, but people keep saying it will break existing code, so that's probably not going to happen in D2. D3 perhaps will be able to clean up a lot of this mess. And frankly, most of the responses on this thread (including my own, I'll admit) are more wishlist items than the truly "redundant" features that Walter referred to initially. And I have to say that in spite of little annoyances here and there, D2 is still the closest to my ideal programming language, and that's unlikely to change anytime soon. What we really need to focus on now is to hone the existing features, clean up the bugs, and improve the implementation, rather than continue to introduce new features and breaking changes. Existing features really need to Just Work(tm). We will drive away many potential D users by incomplete/buggy implementation of advertised features. T -- There are three kinds of people in the world: those who can count, and those who can't.
Apr 30 2012
On Monday, 30 April 2012 at 17:13:36 UTC, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 01:04:01PM -0400, Jonathan M Davis It would be unwise to make major changes to the language at this point. Personally I'd like to see the comma operator removed, but people keep saying it will break existing code, so that's probably not going to happen in D2. D3 perhaps will be able to clean up a lot of this mess.Then perhaps the comma operator can be pushed to the 'depreciated' list for a while; If it breaks anything big and important, you can still compile it. After a while we can see if it should be kept or removed. I think that's the best approach all things considered. Personally, I have yet to really use it outside of a for/foreach statement. On the other hand if it breaks something, generally it will become quite clear where in few the few places and require you to fix and update it before moving on.
Apr 30 2012
On Mon, Apr 30, 2012 at 08:09:31PM +0200, Era Scarecrow wrote:On Monday, 30 April 2012 at 17:13:36 UTC, H. S. Teoh wrote:Actually it's only inside for. A comma in foreach is not a comma operator but a separator (foreach(a,b;c) is not the same as foreach(b;c)). See, that's another case where it only causes confusion. And I've said many times that inside a for, it really should just be special-cased in for syntax. It should not be an operator in general. T -- Right now I'm having amnesia and deja vu at the same time. I think I've forgotten this before.It would be unwise to make major changes to the language at this point. Personally I'd like to see the comma operator removed, but people keep saying it will break existing code, so that's probably not going to happen in D2. D3 perhaps will be able to clean up a lot of this mess.Then perhaps the comma operator can be pushed to the 'depreciated' list for a while; If it breaks anything big and important, you can still compile it. After a while we can see if it should be kept or removed. I think that's the best approach all things considered. Personally, I have yet to really use it outside of a for/foreach statement. On the other hand if it breaks something, generally it will become quite clear where in few the few places and require you to fix and update it before moving on.
Apr 30 2012
On 30-04-2012 20:28, H. S. Teoh wrote:On Mon, Apr 30, 2012 at 08:09:31PM +0200, Era Scarecrow wrote:-- - AlexOn Monday, 30 April 2012 at 17:13:36 UTC, H. S. Teoh wrote:Actually it's only inside for. A comma in foreach is not a comma operator but a separator (foreach(a,b;c) is not the same as foreach(b;c)). See, that's another case where it only causes confusion. And I've said many times that inside a for, it really should just be special-cased in for syntax. It should not be an operator in general. TIt would be unwise to make major changes to the language at this point. Personally I'd like to see the comma operator removed, but people keep saying it will break existing code, so that's probably not going to happen in D2. D3 perhaps will be able to clean up a lot of this mess.Then perhaps the comma operator can be pushed to the 'depreciated' list for a while; If it breaks anything big and important, you can still compile it. After a while we can see if it should be kept or removed. I think that's the best approach all things considered. Personally, I have yet to really use it outside of a for/foreach statement. On the other hand if it breaks something, generally it will become quite clear where in few the few places and require you to fix and update it before moving on.
Apr 30 2012
On Monday, 30 April 2012 at 18:09:32 UTC, Era Scarecrow wrote:Then perhaps the comma operator can be pushed to the 'depreciated' list for a while; If it breaks anything big and important, you can still compile it. After a while we can see if it should be kept or removed. I think that's the best approach all things considered. Personally, I have yet to really use it outside of a for/foreach statement. On the other hand if it breaks something, generally it will become quite clear where in few the few places and require you to fix and update it before moving on.What we need is a "style guide", ala Scott Meyer, i.e try to find D idioms, how to write good code, what to avoid. Because even though it's harder to write bad code in D than in C++, it's always possible to write code with low performance, or be bitten by some traps. Here is an example: http://forum.dlang.org/post/mailman.9.1335539605.24740.digitalmars-d-learn puremagic.com
Apr 30 2012
On 4/30/12 5:15 AM, bearophile wrote:Jonathan M Davis:It's a bit inappropriate to bind Walter to such a social contract upon having asked an informal question. Besides, if we're talking about work of writing posts we should also consider the considerable work of reading certain posts, which are so patronizing as to make reading an exercise in eye rolling.Honestly, I don't think that you _can_ take much from this thread other thanI don't agree, I see some recurring patterns. People have spent energy and time to write lot of answers in this thread, some good answer bits too, so I expect such work to not let be fully wasted. Asking for opinions, receiving lot of them, and then ignoring them all is not a good way to run a community.And thank you for your answer, I always appreciate your answers, but you aren't Walter, that post was for him (and Andrei) to answer :-)FWIW there is little agreement among answers. Eliminating today's semantics of comma inevitably underlies the hope that it can be retrofitted for something else, which I think is near impossible without changing semantics of working code. Then there's a lot of busywork. Eliminating e.g. "with" is going to leave things pretty much where they are with the note some innocently bystanding programs are going to break. One feature to remove stands out - the struct initialization: struct S { int x, y; } S s = { 1, 2 }; This, was noted, makes the order of members effectively part of the struct's interface, which is subtly dangerous. I think we should remove this feature. Andrei
May 01 2012
On Wednesday, 2 May 2012 at 03:22:02 UTC, Andrei Alexandrescu wrote:One feature to remove stands out - the struct initialization: S s = { 1, 2 };I could live without that one, because D has an alternative: auto s = S(1, 2); And I'd be sad if you took that out, as I use it a lot, especially for trivial types: struct Html { string src; } struct Text { string src; } struct Point { int x; int y; } struct Size { int width; int height; } which I like because then we can use the types for overloading, static checks, etc., and it is very very simple to drop in and use. I guess there could be opCalls or constructors, but poo, it works now without that and I like it.
May 01 2012
On Wednesday, 2 May 2012 at 03:38:41 UTC, Adam D. Ruppe wrote:On Wednesday, 2 May 2012 at 03:22:02 UTC, Andrei Alexandrescu wrote:S(...) does not exhibit the same problem as {...} exactly because it has constructors and static opCall. If you change the order of fields in S, you can write a constructor preserving the old behaviour.One feature to remove stands out - the struct initialization: S s = { 1, 2 };I could live without that one, because D has an alternative: auto s = S(1, 2); And I'd be sad if you took that out, as I use it a lot, especially for trivial types: struct Html { string src; } struct Text { string src; } struct Point { int x; int y; } struct Size { int width; int height; } which I like because then we can use the types for overloading, static checks, etc., and it is very very simple to drop in and use. I guess there could be opCalls or constructors, but poo, it works now without that and I like it.
May 01 2012
On 5/2/12 12:20 AM, Jakob Ovrum wrote:S(...) does not exhibit the same problem as {...} exactly because it has constructors and static opCall. If you change the order of fields in S, you can write a constructor preserving the old behaviour.Good observation. So indeed the { ... } case is inferior because there's no reasonable way for the library writer to defend against. Andrei
May 02 2012
On Wednesday, 2 May 2012 at 03:38:41 UTC, Adam D. Ruppe wrote:On Wednesday, 2 May 2012 at 03:22:02 UTC, Andrei Alexandrescu wrote:It has the same problem as the first one: members are part of the interface and a new one: struct literals are impossible if opCall is defined (if I am not mistaken).One feature to remove stands out - the struct initialization: S s = { 1, 2 };I could live without that one, because D has an alternative: auto s = S(1, 2);
May 01 2012
On Wednesday, May 02, 2012 07:17:20 Maxim Fomin wrote:On Wednesday, 2 May 2012 at 03:38:41 UTC, Adam D. Ruppe wrote:Yes, members are part of the interface, but if {1, 2} isn't legal, then their order isn't part of the interface as far as constructing the object is concerned (the memory layout is, so low-level stuff could still be broken by swapping or adding member variables, but the construction doesn't have to stop working like it does with a C struct literal). And defining opCall shouldn't have any effect on S(1, 2). S(1, 2) is clearly calling the constructor. The only reason that you would have a conflict is if you also defined a static opCall which conflicted. If a non-static opCall has _any_ effect on S(1, 2), then it's a bug. - Jonathan M DavisOn Wednesday, 2 May 2012 at 03:22:02 UTC, Andrei Alexandrescu wrote:It has the same problem as the first one: members are part of the interface and a new one: struct literals are impossible if opCall is defined (if I am not mistaken).One feature to remove stands out - the struct initialization: S s = { 1, 2 };I could live without that one, because D has an alternative: auto s = S(1, 2);
May 01 2012
On 5/1/12 11:38 PM, Adam D. Ruppe wrote:On Wednesday, 2 May 2012 at 03:22:02 UTC, Andrei Alexandrescu wrote:Well, so probably we shouldn't remove that feature either :o). AndreiOne feature to remove stands out - the struct initialization: S s = { 1, 2 };I could live without that one, because D has an alternative: auto s = S(1, 2); And I'd be sad if you took that out, as I use it a lot, especially for trivial types: struct Html { string src; } struct Text { string src; } struct Point { int x; int y; } struct Size { int width; int height; } which I like because then we can use the types for overloading, static checks, etc., and it is very very simple to drop in and use. I guess there could be opCalls or constructors, but poo, it works now without that and I like it.
May 02 2012
On 5/2/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:struct S { int x, y; } S s = { 1, 2 }; I think we should remove this feature.But not this, right: S s = { x : 1, y : 2 }; ?
May 01 2012
On Wednesday, 2 May 2012 at 05:25:40 UTC, Andrej Mitrovic wrote:On 5/2/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Yes, these are named parameters. Andrei's point could be made for just about everything that takes two (or more) consecutive integers, like a function signature, so I think it's a bit moot. Unfortunately, only named parameters can solve this problem, but then comes the problem of accepting both order of parameters and named parameters at the same time...struct S { int x, y; } S s = { 1, 2 }; I think we should remove this feature.But not this, right: S s = { x : 1, y : 2 }; ?
May 01 2012
Andrei Alexandrescu:It's a bit inappropriate to bind Walter to such a social contract upon having asked an informal question.Those comments weren't required, but they improve the quality of this community. So it's work and time well spent. Every person attracted to work on D development is a chance to increase significantly the development speed.FWIW there is little agreement among answers.Right, but a thread like this is comparable to the first phase of a Brainstorming process, where ideas are produced freely, where agreement is not required. Later there is a phase of selection, that needs to be based on the quality of the single ideas; because technology/science decisions can't be based (too much) on popularity.Eliminating today's semantics of comma inevitably underlies the hope that it can be retrofitted for something else, which I think is near impossible without changing semantics of working code.Removing/restricting the usage of the comma operator is probably able to avoid some bugs (and increase syntax uniformity in D code written by different programmers), so it has a usefulness even if later they are not used for tuple syntax. How much important such bugs are, is a judgement.One feature to remove stands out - the struct initialization: struct S { int x, y; } S s = { 1, 2 }; This, was noted, makes the order of members effectively part of the struct's interface, which is subtly dangerous. I think we should remove this feature.It's a partially redundant feature, and it's able to introduce some long-term rigidity in the code. On the other hand when you have to write many struct literals, nested inside other literals of different structs, repeating the names introduces a bit of extra redundant code. Thank you for the answers, bye, bearophile
May 02 2012
On 5/2/12 7:52 AM, bearophile wrote:Andrei Alexandrescu:Sorry, here I meant "agreement" in the statistical sense, i.e. there's not a lot of clear collection of features we should remove; for most features that some wanted to get rid of, others had gainful uses. AndreiFWIW there is little agreement among answers.Right, but a thread like this is comparable to the first phase of a Brainstorming process, where ideas are produced freely, where agreement is not required.
May 02 2012
I would say many of the discussion items are to be fixed in a D version "break the world" to be done when D finally becomes famous, similar to Python 3000 plans. Until then the focus should be in fixing the open bugs, deviations to the TDPL, and improving available tools and frameworks. What is the point of having a perfect systems programming language if no one uses it? -- Paulo "bearophile" wrote in message news:tfbtvfccnxluzbuxofot forum.dlang.org... Walter:What's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter & Andrei? Bye, bearophile
Apr 30 2012
On 30-04-2012 01:41, bearophile wrote:Walter:I think the one thing there is universal agreement on is that the comma operator has to go. -- - AlexWhat's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter & Andrei? Bye, bearophile
Apr 30 2012
On Mon, Apr 30, 2012 at 05:26:15PM +0200, Alex Rønne Petersen wrote:On 30-04-2012 01:41, bearophile wrote:[...]Walter:What's your list?This thread now has something like 240 answers (and probably few more will come), and despite some variability in the answers, we have seen several recurring patterns too. So what are the conclusions, take-home insights, and the to-do's to make something in practice, from Walter & Andrei?I think the one thing there is universal agreement on is that the comma operator has to go.[...] +1. Let's rid the comma operator of its miserable existence. T -- Computers aren't intelligent; they only think they are.
Apr 30 2012
On Sun, Apr 29, 2012 at 11:55:43PM -0700, Jonathan M Davis wrote: [...]Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else.[...] So far, I've not seen a single response in favor of keeping the comma operator. T -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.
Apr 30 2012
On Monday, 30 April 2012 at 15:35:19 UTC, H. S. Teoh wrote:So far, I've not seen a single response in favor of keeping the comma operator.I kinda like having it....
Apr 30 2012
On Monday, 30 April 2012 at 15:38:32 UTC, Adam D. Ruppe wrote:On Monday, 30 April 2012 at 15:35:19 UTC, H. S. Teoh wrote:I too and I am afraid that disallowing it would result that something would be broken.So far, I've not seen a single response in favor of keeping the comma operator.I kinda like having it....
Apr 30 2012
On Monday, 30 April 2012 at 15:35:19 UTC, H. S. Teoh wrote:So far, I've not seen a single response in favor of keeping the comma operator.Very few want it, but as a practicality, it would be unwise to remove it (would break an awful lot of code).
Apr 30 2012
Le 30/04/2012 18:13, Peter Alexander a écrit :On Monday, 30 April 2012 at 15:35:19 UTC, H. S. Teoh wrote:Some have proposed that comma operator could create tuples. If void members in tuples are automagically skipped, this won't break that many code. A first step in that direction would be to deprecate comma expression where expressions before the last one have not type void.So far, I've not seen a single response in favor of keeping the comma operator.Very few want it, but as a practicality, it would be unwise to remove it (would break an awful lot of code).
Apr 30 2012
On 04/30/2012 05:36 PM, H. S. Teoh wrote:On Sun, Apr 29, 2012 at 11:55:43PM -0700, Jonathan M Davis wrote: [...]I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else.[...] So far, I've not seen a single response in favor of keeping the comma operator. T
Apr 30 2012
On 04/30/2012 08:46 PM, Timon Gehr wrote:On 04/30/2012 05:36 PM, H. S. Teoh wrote:(outside for)On Sun, Apr 29, 2012 at 11:55:43PM -0700, Jonathan M Davis wrote: [...]I think I use it about every 60 lines of code.Honestly, I don't think that you _can_ take much from this thread other than the fact that pretty _every_ feature is wanted and used by someone, even if other people hate it. Pretty much every feature listed as undesirable by someone was listed as desirable by someone else.[...] So far, I've not seen a single response in favor of keeping the comma operator. TAlso, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.
Apr 30 2012
On Monday, 30 April 2012 at 18:46:02 UTC, Timon Gehr wrote:On 04/30/2012 05:36 PM, H. S. Teoh wrote:Care to show some examples? DavidSo far, I've not seen a single response in favor of keeping the comma operator.I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.
Apr 30 2012
On Mon, Apr 30, 2012 at 08:46:02PM +0200, Timon Gehr wrote:On 04/30/2012 05:36 PM, H. S. Teoh wrote:[...][...]So far, I've not seen a single response in favor of keeping the comma operator.I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.We already have a reuse waiting in the line up, for a looong time. Native tuple syntax. T -- Doubtless it is a good thing to have an open mind, but a truly open mind should be open at both ends, like the food-pipe, with the capacity for excretion as well as absorption. -- Northrop Frye
Apr 30 2012
Timon Gehr:I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.Commas do cause some bugs, so maybe they are worth restricting (further) even if their syntax doesn't get reused. Bye, bearophile
Apr 30 2012
Le 30/04/2012 22:44, bearophile a écrit :Timon Gehr:+1 Looking for a , instead of a ; is really painful. It doesn't occur often, but when it does, you remember it for quite a long time.I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.Commas do cause some bugs, so maybe they are worth restricting (further) even if their syntax doesn't get reused. Bye, bearophile
Apr 30 2012
On Monday, 30 April 2012 at 22:04:16 UTC, deadalnix wrote:Looking for a , instead of a ; is really painful. It doesn't occur often, but when it does, you remember it for quite a long time.Also consider that at least on many European keyboard layouts, ',' and ';' share the same key… David
Apr 30 2012
On Sunday, April 29, 2012 19:37:50 H. S. Teoh wrote:On Sun, Apr 29, 2012 at 08:42:23PM +0200, Andrej Mitrovic wrote:Well, it's both really. If the language spec was exact enough, it would say _exactly_ what the correct behavior is here, in which case, either the compiler is currently doing the right thing or it's not, depending on the spec. But the spec isn't that exact, so in some respects, the compiler _is_ the spec. Certainly, the way that this behaves in the language right now is a matter of how the compiler behaves. Ideally though, there would be zero difference between using a property and a public member variable save for taking its address (which should probably just be illegal for property functions). I've been tempted to add an enhancement request for putting property on public member variables to make it so that anything which would would break code if it were switched to a property function wouldn't be legal (such as taking its address). Unfortunately, right now that would include stuff like ++. - Jonathan M DavisOn 4/29/12, Jacob Carlborg <doob me.com> wrote:[...] To me, the compiler needs to be fixed so that anytime the return value of a property is used as an lvalue, it should always try to call the setter function, or some kind of setter function, instead of the getter (unless there's no setter, in which case it's OK to call the getter). I chalk this up to a compiler issue, not a language issue.In principle I agree with you. But in practice this doesn't always work. Take this for example: Prints "0" and "1" as expected. If we now change "point" to a property like this: It will now print "0" and "0". This is a silently breaking change. Sure you can change "point" to return by reference..This is a great point and an issue I've ran into and talked about before. The compiler really ought to try and convert a call like this: foo.property++; foo.property+=10; into e.g.: foo.property = foo.property.opAdd(1); foo.property = foo.property.opAdd(10); It would make for some really nice APIs if this feature was available.
Apr 29 2012
On 2012-04-30 04:41, Jonathan M Davis wrote:Ideally though, there would be zero difference between using a property and a public member variable save for taking its address (which should probably just be illegal for property functions). I've been tempted to add an enhancement request for putting property on public member variables to make it so that anything which would would break code if it were switched to a property function wouldn't be legal (such as taking its address). Unfortunately, right now that would include stuff like ++. - Jonathan M DavisI would rather have property on instance variables be a syntax sugar for implementing property functions. Basically virtual instance variables. -- /Jacob Carlborg
Apr 30 2012
On 30-04-2012 09:58, Jacob Carlborg wrote:On 2012-04-30 04:41, Jonathan M Davis wrote:Then there better be a way to mark them final too. ;) -- - AlexIdeally though, there would be zero difference between using a property and a public member variable save for taking its address (which should probably just be illegal for property functions). I've been tempted to add an enhancement request for putting property on public member variables to make it so that anything which would would break code if it were switched to a property function wouldn't be legal (such as taking its address). Unfortunately, right now that would include stuff like ++. - Jonathan M DavisI would rather have property on instance variables be a syntax sugar for implementing property functions. Basically virtual instance variables.
Apr 30 2012
On 2012-04-30 17:27, Alex Rønne Petersen wrote:On 30-04-2012 09:58, Jacob Carlborg wrote:Then what's the point of having a method? Just use a public instance variable. -- /Jacob CarlborgI would rather have property on instance variables be a syntax sugar for implementing property functions. Basically virtual instance variables.Then there better be a way to mark them final too. ;)
Apr 30 2012
On 30-04-2012 21:43, Jacob Carlborg wrote:On 2012-04-30 17:27, Alex Rønne Petersen wrote:Encapsulation. I want contracts in my properties. -- - AlexOn 30-04-2012 09:58, Jacob Carlborg wrote:Then what's the point of having a method? Just use a public instance variable.I would rather have property on instance variables be a syntax sugar for implementing property functions. Basically virtual instance variables.Then there better be a way to mark them final too. ;)
Apr 30 2012
On 2012-04-30 21:56, Alex Rønne Petersen wrote:On 30-04-2012 21:43, Jacob Carlborg wrote:Aha, didn't thin of that. Sure, why not. -- /Jacob CarlborgOn 2012-04-30 17:27, Alex Rønne Petersen wrote:Encapsulation. I want contracts in my properties.On 30-04-2012 09:58, Jacob Carlborg wrote:Then what's the point of having a method? Just use a public instance variable.I would rather have property on instance variables be a syntax sugar for implementing property functions. Basically virtual instance variables.Then there better be a way to mark them final too. ;)
May 01 2012
On Monday, April 30, 2012 07:46:48 Andrej Mitrovic wrote:On 4/30/12, Jonathan M Davis <jmdavisProg gmx.com> wrote:Yes, but that still compiles everything. It just gives you a convenient way to have a unit test executable separate from your normal executable. - Jonathan M DavisOn Sunday, April 29, 2012 21:56:08 H. S. Teoh wrote:For RDMD you can do: version(unittest) { } else void main() { // regular code here } And then you can invoke rdmd with --unittest and --main to insert an empty main function when unittesting. Personally I put in a stub main so I don't depend on rdmd features like --main: version(unittest) { void main(string[] args) { } } // stub main else void main() { // regular code here }I wonder if dmd (or rdmd) should have a mode where it *only* compiles unittest code (i.e., no main() -- the resulting exe just runs unittests and nothing else).
Apr 29 2012
On 4/28/2012 11:47 AM, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?This certainly seems to have become the biggest thread ever!
Apr 30 2012
On 5/1/12 2:24 AM, Walter Bright wrote:On 4/28/2012 11:47 AM, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?This certainly seems to have become the biggest thread ever!
Apr 30 2012
On Monday, 30 April 2012 at 19:24:50 UTC, Walter Bright wrote:On 4/28/2012 11:47 AM, Walter Bright wrote:Yes, this is a very interesting discussion, even for a n00b like me ! (and even if i didn't understand everything)Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?This certainly seems to have become the biggest thread ever!
Apr 30 2012
On Monday, 30 April 2012 at 19:24:50 UTC, Walter Bright wrote:This certainly seems to have become the biggest thread ever!What did you expect, really ? That people would say "nothing, the language is perfect" ? :D When I saw your question, I immediately thought "damn, Walter is starting a troll thread for fun, it's gonna be a huge waste of time". :D But then I changed my mind, because what I saw, - and that's what I expected actually -, is that almost everybody had a different list from other people. Which is in fact good, because that means that everybody uses his own subset of the language for his own use, and although there is a common ground, the union of all subsets seems to pretty much fill the "design space" of the language. In the end, very few "features" seem to be universally disdained (the comma operator seems to come regularly, though, but even that one has supporters). Which means to me that in terms of overall design, the language is not in a bad shape at all. So the design phase seems almost complete. The real effort now must be to finish the implementation, and build a full productive ecosystem. And I suppose we are still far from that goal.
Apr 30 2012
Le 30/04/2012 22:52, SomeDude a écrit :In the end, very few "features" seem to be universally disdained (the comma operator seems to come regularly, though, but even that one has supporters). Which means to me that in terms of overall design, the language is not in a bad shape at all.I wouldn't say supporter, but some people think it doesn't worth the cost of breaking code. BTW, you'll find lazy too.
Apr 30 2012
On 05/01/2012 12:12 AM, deadalnix wrote:Le 30/04/2012 22:52, SomeDude a écrit :call by name is useful.In the end, very few "features" seem to be universally disdained (the comma operator seems to come regularly, though, but even that one has supporters). Which means to me that in terms of overall design, the language is not in a bad shape at all.I wouldn't say supporter, but some people think it doesn't worth the cost of breaking code. BTW, you'll find lazy too.
Apr 30 2012
On 28/04/12 20:47, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse ============================= About the NCEG operators -- the reason they're redundant is that you practically always want to treat NaN separately. I've tried _very_ hard to come up with uses for them, but without success. The thing I've used the most is: x !<>= x which is a kind of built-in isNaN(x), but that can also be rewritten as: x != x Initially I though you'd do things like real func(real x) { // x must be non-NaN and in the range -x.infinity .. N if (x !< N) return real.nan; but even that isn't convincing, because if x is NaN you should be returning x, so that you preserve NaN payloads. I think I have used these guys more than anyone else, but I still haven't found a single use case that stands up to scrutiny.
May 03 2012
On 5/3/12 9:55 AM, Don Clugston wrote:On 28/04/12 20:47, Walter Bright wrote:Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o). AndreiAndrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse
May 03 2012
On 03/05/12 16:13, Andrei Alexandrescu wrote:On 5/3/12 9:55 AM, Don Clugston wrote:Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.On 28/04/12 20:47, Walter Bright wrote:Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse
May 03 2012
On 03-05-2012 17:13, Don Clugston wrote:On 03/05/12 16:13, Andrei Alexandrescu wrote:But not quite everything yet. When I tried to pure/nothrow/ safe-ify std.math[special], I eventually stumbled upon code that used core.stdc.math. It would definitely be nice if we could completely kill any dependency on that module, so we can actually make proper use of pure/nothrow/ safe, etc. -- - AlexOn 5/3/12 9:55 AM, Don Clugston wrote:Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.On 28/04/12 20:47, Walter Bright wrote:Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse
May 03 2012
On May 3, 2012, at 9:58 AM, Alex R=F8nne Petersen wrote:On 03-05-2012 17:13, Don Clugston wrote:std.math.=20 =20 Well, they are also used in druntime, in core.stdc.math =20 BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in ==20 But not quite everything yet. When I tried to pure/nothrow/ safe-ify =std.math[special], I eventually stumbled upon code that used = core.stdc.math.=20 It would definitely be nice if we could completely kill any dependency =on that module, so we can actually make proper use of = pure/nothrow/ safe, etc. I've always thought use of core.stdc as an indicator for things that = should be added to Phobos. Really, core.stdc should only be used by = apps ported from C to D, not by apps written from scratch in D.=
May 03 2012
On May 3, 2012, at 8:13 AM, Don Clugston wrote:On 03/05/12 16:13, Andrei Alexandrescu wrote:because=20 =20 Good ones. In fact I even discounted them from this discussion =seems to be growing -- people are adding more things to it.I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. =20 One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).=20 Well, they are also used in druntime, in core.stdc.math =20 BTW I *hate* that module, I don't know why it exists. Even worse, it =Practically everything in there has a better implementation in =std.math. core.stdc.math corresponds to C99's math.h and is there as a part of the = standard C interface. It should only contain the required C99 = prototypes, and in some cases functions if the C implementation is a = macro. If there is anything nonstandard in there, I'm not aware of it.=
May 03 2012
On 03.05.2012 21:08, Sean Kelly wrote:On May 3, 2012, at 8:13 AM, Don Clugston wrote:Yes, but why do we have it? We're not C. Some of the std C functions aren't implemented correctly (especially the FreeBSD long double functions, which are completely wrong). And that shouldn't be D's problem. Even when they are, they're not pure nothrow, and sometimes they have really silly names (I'm looking at you, tgamma() ) Quite absurdly, the DMC gamma function is a port from the D version. Why include it twice??On 03/05/12 16:13, Andrei Alexandrescu wrote:core.stdc.math corresponds to C99's math.h and is there as a part of the standard C interface. It should only contain the required C99 prototypes, and in some cases functions if the C implementation is a macro. If there is anything nonstandard in there, I'm not aware of it.Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.
May 03 2012
On May 3, 2012, at 1:11 PM, Don wrote:On 03.05.2012 21:08, Sean Kelly wrote:becauseOn May 3, 2012, at 8:13 AM, Don Clugston wrote: =20On 03/05/12 16:13, Andrei Alexandrescu wrote:=20 =20 Good ones. In fact I even discounted them from this discussion =mentionI'd already considered them gone. Walter agreed that I don't =accept-invalidthem in TDPL, with the intent to have them peter out. =20 One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an =seems to be growing -- people are adding more things to it.bug :o).=20 Well, they are also used in druntime, in core.stdc.math =20 BTW I *hate* that module, I don't know why it exists. Even worse, it =std.math.Practically everything in there has a better implementation in =the standard C interface. It should only contain the required C99 = prototypes, and in some cases functions if the C implementation is a = macro. If there is anything nonstandard in there, I'm not aware of it.=20 core.stdc.math corresponds to C99's math.h and is there as a part of ==20 Yes, but why do we have it? We're not C.Mostly because it was handy to fall back on the C API before Phobos was = so well fleshed-out. Today, I think it mostly exists to ease porting of = C apps.=
May 03 2012
Le 03/05/2012 22:43, Sean Kelly a écrit :On May 3, 2012, at 1:11 PM, Don wrote:So they probably belongs to deimos.On 03.05.2012 21:08, Sean Kelly wrote:Mostly because it was handy to fall back on the C API before Phobos was so well fleshed-out. Today, I think it mostly exists to ease porting of C apps.On May 3, 2012, at 8:13 AM, Don Clugston wrote:Yes, but why do we have it? We're not C.On 03/05/12 16:13, Andrei Alexandrescu wrote:core.stdc.math corresponds to C99's math.h and is there as a part of the standard C interface. It should only contain the required C99 prototypes, and in some cases functions if the C implementation is a macro. If there is anything nonstandard in there, I'm not aware of it.Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.
May 03 2012
On May 3, 2012, at 2:16 PM, deadalnix <deadalnix gmail.com> wrote:Le 03/05/2012 22:43, Sean Kelly a =C3=A9crit :eOn May 3, 2012, at 1:11 PM, Don wrote: =20On 03.05.2012 21:08, Sean Kelly wrote:On May 3, 2012, at 8:13 AM, Don Clugston wrote: =20On 03/05/12 16:13, Andrei Alexandrescu wrote:=20 =20 Good ones. In fact I even discounted them from this discussion becaus=I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. =20 One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid=eems to be growing -- people are adding more things to it.bug :o).=20 Well, they are also used in druntime, in core.stdc.math =20 BTW I *hate* that module, I don't know why it exists. Even worse, it s=h.Practically everything in there has a better implementation in std.mat=e standard C interface. It should only contain the required C99 prototypes,= and in some cases functions if the C implementation is a macro. If there i= s anything nonstandard in there, I'm not aware of it.=20 core.stdc.math corresponds to C99's math.h and is there as a part of th=o well fleshed-out. Today, I think it mostly exists to ease porting of C ap= ps.=20 Yes, but why do we have it? We're not C.=20 Mostly because it was handy to fall back on the C API before Phobos was s==20 So they probably belongs to deimos.Except that they're used by druntime, both explicitly and publicly imported b= y core.sys.posix.=20=
May 03 2012
Le 04/05/2012 02:03, Sean Kelly a écrit :On May 3, 2012, at 2:16 PM, deadalnix<deadalnix gmail.com> wrote:I may scare people here, but as Deimos is only declaration, I see no problem to use a deimos header in druntime.Le 03/05/2012 22:43, Sean Kelly a écrit :Except that they're used by druntime, both explicitly and publicly imported by core.sys.posix.On May 3, 2012, at 1:11 PM, Don wrote:So they probably belongs to deimos.On 03.05.2012 21:08, Sean Kelly wrote:Mostly because it was handy to fall back on the C API before Phobos was so well fleshed-out. Today, I think it mostly exists to ease porting of C apps.On May 3, 2012, at 8:13 AM, Don Clugston wrote:Yes, but why do we have it? We're not C.On 03/05/12 16:13, Andrei Alexandrescu wrote:core.stdc.math corresponds to C99's math.h and is there as a part of the standard C interface. It should only contain the required C99 prototypes, and in some cases functions if the C implementation is a macro. If there is anything nonstandard in there, I'm not aware of it.Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.
May 06 2012
On 5/6/2012 8:09 AM, deadalnix wrote:I may scare people here, but as Deimos is only declaration, I see no problem to use a deimos header in druntime.I do, because it adds another dependency on something not in the main download.
May 06 2012
On Thursday, May 03, 2012 13:43:11 Sean Kelly wrote:On May 3, 2012, at 1:11 PM, Don wrote:In principle, having prototypes for the entire standard C library in druntime seems like a good idea to me. In practice though, it could cause problems due to people using the C functions rather than the D functions for some things (e.g. the math functions). If we properly documented them all though, we could then put comments about the correct D function to use to replace each C function which has a D replacement, and then it could actually help people move away from the C functions. - Jonathan M DavisOn 03.05.2012 21:08, Sean Kelly wrote:Mostly because it was handy to fall back on the C API before Phobos was so well fleshed-out. Today, I think it mostly exists to ease porting of C apps.On May 3, 2012, at 8:13 AM, Don Clugston wrote:Yes, but why do we have it? We're not C.On 03/05/12 16:13, Andrei Alexandrescu wrote:core.stdc.math corresponds to C99's math.h and is there as a part of the standard C interface. It should only contain the required C99 prototypes, and in some cases functions if the C implementation is a macro. If there is anything nonstandard in there, I'm not aware of it.>Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.>>
May 03 2012
On 5/3/2012 8:13 AM, Don Clugston wrote:Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. It's there to make converting C code to D code easier.Practically everything in there has a better implementation in std.math.Yup. But also note that the only "implementations" in there are things that are done as macros in C's math.h, meaning they're trivial.
May 03 2012
On Thursday, 3 May 2012 at 22:57:02 UTC, Walter Bright wrote:On 5/3/2012 8:13 AM, Don Clugston wrote:This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code. IMO C headers should be moved to Deimos, and should be clearly documented that their intended purpose is to _link_ D code with the C runtime.Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. It's there to make converting C code to D code easier.
May 06 2012
On Sunday, May 06, 2012 21:18:38 foobar wrote:On Thursday, 3 May 2012 at 22:57:02 UTC, Walter Bright wrote:Then you misunderstand. One of the tenets that D holds to is that any C/C++ code either compiles as valid D code with identical semantics, or it doesn't compile as D code (there are a few minor exceptions - such as static arrays being passed by value - but not many). This means that we can break compatibility with C/C++ and do our own thing for a lot of stuff but that we can't just redefine what stuff does such that it would silently break code when it's ported from C/C++ to D. That approach is _very_ different from C++'s approach where valid C code pretty much _always_ compiles identically in C++ (the fact that C++ added keywords being the only exception that I can think of at the moment), but that doesn't mean that we don't care about code portability from C/C++ to D. There's a huge difference between designing a language such that porting code to it from another language isn't error-prone and making the new language source compatibile. D does the former. C++ does the latter. Being able to port code from C/C++ to D without having to worry about silent breakage _is_ one of D's goals. - Jonathan M DavisOn 5/3/2012 8:13 AM, Don Clugston wrote:This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code.Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. It's there to make converting C code to D code easier.
May 06 2012
On 07-05-2012 00:06, Jonathan M Davis wrote:On Sunday, May 06, 2012 21:18:38 foobar wrote:So basically, language design advances on our front have to be hindered by some kind of compatibility that has *very* questionable usefulness. I have never copy/pasted C/C++ code into D. Ever. Even when making bindings, I type declarations out manually to be completely sure I get them right. This is like when C++ tried to be source compatible with C. In practice, nearly no one just took a C source base and compiled it as C++ and called it a day, because of two reasons: 1) C++ wasn't actually source compatible enough so that this would just be a tiny build system change, 2) there would be zero gain in doing it. I haven't ever copy/pasted C code into C++ either, now that I think about it. I don't think you're going to see people port their large C source bases to D just for the sake of doing it. I think, rather, you'll see them write bindings because that's the more pragmatic and time-efficient approach. BTW, if we're so focused on C/C++ source compatibility, what about the unfortunate D1 folks? We seem to largely not care about source compatibility for their code at all. Seems like our priorities are quite skewed.On Thursday, 3 May 2012 at 22:57:02 UTC, Walter Bright wrote:Then you misunderstand. One of the tenets that D holds to is that any C/C++ code either compiles as valid D code with identical semantics, or it doesn't compile as D code (there are a few minor exceptions - such as static arrays being passed by value - but not many). This means that we can break compatibility with C/C++ and do our own thing for a lot of stuff but that we can't just redefine what stuff does such that it would silently break code when it's ported from C/C++ to D.On 5/3/2012 8:13 AM, Don Clugston wrote:This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code.Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. It's there to make converting C code to D code easier.That approach is _very_ different from C++'s approach where valid C code pretty much _always_ compiles identically in C++ (the fact that C++ added keywords being the only exception that I can think of at the moment), but that doesn't mean that we don't care about code portability from C/C++ to D. There's a huge difference between designing a language such that porting code to it from another language isn't error-prone and making the new language source compatibile. D does the former. C++ does the latter.http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B We probably have many of the incompatibilities mentioned there too.Being able to port code from C/C++ to D without having to worry about silent breakage _is_ one of D's goals. - Jonathan M Davis-- - Alex
May 06 2012
On Monday, May 07, 2012 07:48:05 Alex R=C3=B8nne Petersen wrote:On 07-05-2012 00:06, Jonathan M Davis wrote:nyOn Sunday, May 06, 2012 21:18:38 foobar wrote:On Thursday, 3 May 2012 at 22:57:02 UTC, Walter Bright wrote:=20 Then you misunderstand. One of the tenets that D holds to is that a=On 5/3/2012 8:13 AM, Don Clugston wrote:=20 This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code.Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.=20 It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. =20 It's there to make converting C code to D code easier.tC/C++ code either compiles as valid D code with identical semantics, or i=asdoesn't compile as D code (there are a few minor exceptions - such =t westatic arrays being passed by value - but not many). This means tha=fcan break compatibility with C/C++ and do our own thing for a lot o=wouldstuff but that we can't just redefine what stuff does such that it =edsilently break code when it's ported from C/C++ to D.=20 So basically, language design advances on our front have to be hinder=by some kind of compatibility that has *very* questionable usefulness=. Ihave never copy/pasted C/C++ code into D. Ever. Even when making bindings, I type declarations out manually to be completely sure I ge=tthem right. =20 This is like when C++ tried to be source compatible with C. In practi=ce,nearly no one just took a C source base and compiled it as C++ and called it a day, because of two reasons: 1) C++ wasn't actually sourc=ecompatible enough so that this would just be a tiny build system chan=ge,2) there would be zero gain in doing it. I haven't ever copy/pasted C=code into C++ either, now that I think about it. =20 I don't think you're going to see people port their large C source ba=sesto D just for the sake of doing it. I think, rather, you'll see them write bindings because that's the more pragmatic and time-efficient approach.We only require source compatibility so far as C/C++ code which compile= s as D=20 code needs to have the same semantics as it does in C/C++. This actuall= y=20 causes very few restrictions, because D's syntax differs enough that co= mpiling=20 C/C++ as D code breaks _very_ quickly. But by having that level of=20 compatability, we make it so that porting code from C/C++ (which people= _will_=20 do, even if the majority of D programmers don't) doesn't break silently= . The only place that I'm aware of where this policy has caused some prob= lems is=20 arithmetic and integral promotions. There a few cases where it would be= nice=20 to change the semantics for that, but for the most part, the C/C++ sema= ntics=20 are fine, and I'm sure that Walter considers whatever loss we get there= to be=20 worth the gain in making it so that C/C++ code ports to D without break= ing=20 silently. I really don't think that this level of compatibility with C/C++ has co= st us=20 much. As similar as D's syntax is, it differs in so many small ways, th= at C/C++=20 code quickly fails to compile as D code, and so the small level of=20 compatibility that we insist on doesn't affect much.BTW, if we're so focused on C/C++ source compatibility, what about th=eunfortunate D1 folks? We seem to largely not care about source compatibility for their code at all. Seems like our priorities are qu=iteskewed.D was frozen as D1 when it was so that the folks using D for real work = could=20 continue to do so while major breakages continued to occur as the langu= age was=20 expanded and refined (in particular, const was going to be added, which= was=20 going to break a _lot_). It was _never_ intended that D2 be source comp= atible=20 with D1 or that D1 even stick around long term. It was merely a stable = branch=20 which was left around in order to let people continue to use the langua= ge for=20 real work while the main branch continued to be developed. In the long = run, D1=20 will be pretty much dead, while we'll still have to worry about people = porting=20 C/C++ code to D for pretty much forever. - Jonathan M Davis
May 06 2012
On 2012-05-07 08:03, Jonathan M Davis wrote:The only place that I'm aware of where this policy has caused some problems is arithmetic and integral promotions. There a few cases where it would be nice to change the semantics for that, but for the most part, the C/C++ semantics are fine, and I'm sure that Walter considers whatever loss we get there to be worth the gain in making it so that C/C++ code ports to D without breaking silently.I had some problems with floats being default initialized to NaN. -- /Jacob Carlborg
May 07 2012
On 07-05-2012 09:10, Jacob Carlborg wrote:On 2012-05-07 08:03, Jonathan M Davis wrote:I still think floats being initialized to NaN is an atrocity... -- - AlexThe only place that I'm aware of where this policy has caused some problems is arithmetic and integral promotions. There a few cases where it would be nice to change the semantics for that, but for the most part, the C/C++ semantics are fine, and I'm sure that Walter considers whatever loss we get there to be worth the gain in making it so that C/C++ code ports to D without breaking silently.I had some problems with floats being default initialized to NaN.
May 07 2012
On Mon, May 7, 2012 at 2:10 AM, Jacob Carlborg <doob me.com> wrote:On 2012-05-07 08:03, Jonathan M Davis wrote: The only place that I'm aware of where this policy has caused someThat's still correct behavior for C, actually. Using an uninitialized variable in C results in undefined behavior, so D still complies with C requirements when it initializes floats to NaN. I'm guessing there's more to it than that, though, because code that uses uninitialized floats was probably wrong to begin with.problems is arithmetic and integral promotions. There a few cases where it would be nice to change the semantics for that, but for the most part, the C/C++ semantics are fine, and I'm sure that Walter considers whatever loss we get there to be worth the gain in making it so that C/C++ code ports to D without breaking silently.I had some problems with floats being default initialized to NaN.
May 07 2012
On 05/07/2012 03:22 AM, Andrew Wiley wrote:For variables with static storage, C initializes them by default to zero. It's in the spec.I had some problems with floats being default initialized to NaN.That's still correct behavior for C, actually. Using an uninitialized variable in C results in undefined behavior, so D still complies with C requirements when it initializes floats to NaN.
May 07 2012
On 2012-05-07 07:48, Alex Rønne Petersen wrote:So basically, language design advances on our front have to be hindered by some kind of compatibility that has *very* questionable usefulness. I have never copy/pasted C/C++ code into D. Ever. Even when making bindings, I type declarations out manually to be completely sure I get them right.I've created bindings for libclang, I did that by copy-pasting the C code and then some quick search-and-replace. Although this is the only library I manged to create bindings for this easy. -- /Jacob Carlborg
May 07 2012
On 07-05-2012 09:07, Jacob Carlborg wrote:On 2012-05-07 07:48, Alex Rønne Petersen wrote:But declarations are very different from actual statements and expressions (I assume you mean declarations?). -- - AlexSo basically, language design advances on our front have to be hindered by some kind of compatibility that has *very* questionable usefulness. I have never copy/pasted C/C++ code into D. Ever. Even when making bindings, I type declarations out manually to be completely sure I get them right.I've created bindings for libclang, I did that by copy-pasting the C code and then some quick search-and-replace. Although this is the only library I manged to create bindings for this easy.
May 07 2012
On 2012-05-07 09:09, Alex Rønne Petersen wrote:But declarations are very different from actual statements and expressions (I assume you mean declarations?).That's true. Yes, declarations. -- /Jacob Carlborg
May 07 2012
On Sunday, 6 May 2012 at 22:06:32 UTC, Jonathan M Davis wrote:I have a three main problems with the above: a. C++ is *not* fully source compatible with C, especially the latest C99 conflicts with C++ IIRC. b. D isn't either - there are already semantics changes compared to C, as you said so yourself, e.g. static arrays, default initialization of static floats, etc. c. If this is currently a goal of D it really shouldn't be - it prevents us from fixing design bugs we inherited from C such as implicit numeric coercions. As others said, the only thing that sort-of makes sense is to copy/paste *declarations* and even those are different enough in D that they deserve at least a look over to make sure they are correct. We shouldn't promote this "goal" at all especially given that it isn't even guarantied to be 100% correct in all cases. Really what we should be promoting is the fact that D is _link_ compatible with C and allows you to use existing C code _without_ porting it to D.This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code.Then you misunderstand. One of the tenets that D holds to is that any C/C++ code either compiles as valid D code with identical semantics, or it doesn't compile as D code (there are a few minor exceptions - such as static arrays being passed by value - but not many). This means that we can break compatibility with C/C++ and do our own thing for a lot of stuff but that we can't just redefine what stuff does such that it would silently break code when it's ported from C/C++ to D. That approach is _very_ different from C++'s approach where valid C code pretty much _always_ compiles identically in C++ (the fact that C++ added keywords being the only exception that I can think of at the moment), but that doesn't mean that we don't care about code portability from C/C++ to D. There's a huge difference between designing a language such that porting code to it from another language isn't error-prone and making the new language source compatibile. D does the former. C++ does the latter. Being able to port code from C/C++ to D without having to worry about silent breakage _is_ one of D's goals. - Jonathan M Davis
May 08 2012
On 5/8/12, foobar <foo bar.com> wrote:a. C++ is *not* fully source compatible with C, especially the latest C99 conflicts with C++ IIRC.Yeah there's a nice list in the C++ standard, Annex C.1 (C++ and ISO C). PDF: www-d0.fnal.gov/~dladams/cxx_standard.pdf
May 08 2012
foobar:As others said, the only thing that sort-of makes sense is to copy/paste *declarations* and even those are different enough in D that they deserve at least a look over to make sure they are correct. We shouldn't promote this "goal" at all especially given that it isn't even guarantied to be 100% correct in all cases. Really what we should be promoting is the fact that D is _link_ compatible with C and allows you to use existing C code _without_ porting it to D.For various reasons I have translated many times routines, functions and other small and medium amounts of C code to D. And in many cases I have used the C std lib functions to circumvent bugs or limitations or performance problems of Phobos. In both cases I have found the C functions quite useful, so moving them into not built-in stuff is bad for me. The risk of using C functions by mistake is low enough. Bye, bearophile
May 08 2012
On Tuesday, 8 May 2012 at 13:57:30 UTC, bearophile wrote:in many cases I have used the C std lib functions to circumvent bugs or limitations or performance problems of Phobos. In bothI tend to agree with the performance aspect. I just got done with a very challenging class where we solved programming contest style problems ... we got bonus points for the fastest solution (or solutions that could solve extended versions of the problems). It was extremely useful for me to be able to use the C versions of functions. Especially I/O because it made it significantly faster to do some things. That said, some of the things I was doing I would never advocate for being easy/possible with D's I/O.
May 08 2012
On Tuesday, 8 May 2012 at 13:57:30 UTC, bearophile wrote:foobar:That does not contradict what I said. No one stops you from _translating_ C/C++ code (or any other language for that matter) to D. You shouldn't however rely on _copy/pasting_ C code and expect it to magically just work with 100% certainty. I also did not say that using C headers should be forbidden, merely that it should obey the code organization - the current scheme which was defined by Walter is to put such headers in Deimos. I wouldn't mind if Deimos would come bundled with the D tool-chain or be easily accessible via a package manager, Just that code should be kept organized according to our own defined scheme. Besides, what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?As others said, the only thing that sort-of makes sense is to copy/paste *declarations* and even those are different enough in D that they deserve at least a look over to make sure they are correct. We shouldn't promote this "goal" at all especially given that it isn't even guarantied to be 100% correct in all cases. Really what we should be promoting is the fact that D is _link_ compatible with C and allows you to use existing C code _without_ porting it to D.For various reasons I have translated many times routines, functions and other small and medium amounts of C code to D. And in many cases I have used the C std lib functions to circumvent bugs or limitations or performance problems of Phobos. In both cases I have found the C functions quite useful, so moving them into not built-in stuff is bad for me. The risk of using C functions by mistake is low enough. Bye, bearophile
May 08 2012
On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc. -Lars
May 08 2012
On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc. -Lars
May 08 2012
On Tuesday, 8 May 2012 at 16:35:05 UTC, foobar wrote:On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:Um... so you don't mind the C/POSIX declarations being there, you just want them to be private so you aren't tempted to use them in your own code? -LarsOn Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc. -Lars
May 08 2012
On Tuesday, 8 May 2012 at 17:03:10 UTC, Lars T. Kyllingstad wrote:On Tuesday, 8 May 2012 at 16:35:05 UTC, foobar wrote:Yes, pretty much. They are an implementation detail of druntime/phobos. Other vendors may choose to implement the tool-chain with another language in mind and as long as the API remains the same I shouldn't need to care e.g. how the GC allocation is implemented (Perhaps it's done with FORTRAN's memory allocation routines). If I ,the user, want to interface with C I need to use the "official" C headers in Deimos. This is after all the official location for that.On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:Um... so you don't mind the C/POSIX declarations being there, you just want them to be private so you aren't tempted to use them in your own code? -LarsOn Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc. -Lars
May 08 2012
On Tuesday, 8 May 2012 at 17:24:24 UTC, foobar wrote:On Tuesday, 8 May 2012 at 17:03:10 UTC, Lars T. Kyllingstad wrote:BTW, it makes sense even if druntime is implemented with C/POSIX - it decouples the user-facing headers from those used by the runtime. the runtime could depend on an older stable version than the one exposed to the users. I assume druntime/phobos uses some windows APIs in their implementations. Now consider the new winRT API for windows. It should be a matter of updating the headers in a separate repository so that it would be exposed to end-users without waiting on a druntime update to utilize those APIs.On Tuesday, 8 May 2012 at 16:35:05 UTC, foobar wrote:Yes, pretty much. They are an implementation detail of druntime/phobos. Other vendors may choose to implement the tool-chain with another language in mind and as long as the API remains the same I shouldn't need to care e.g. how the GC allocation is implemented (Perhaps it's done with FORTRAN's memory allocation routines). If I ,the user, want to interface with C I need to use the "official" C headers in Deimos. This is after all the official location for that.On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:Um... so you don't mind the C/POSIX declarations being there, you just want them to be private so you aren't tempted to use them in your own code? -LarsOn Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc. -Lars
May 08 2012
On May 8, 2012, at 10:24 AM, foobar wrote:On Tuesday, 8 May 2012 at 17:03:10 UTC, Lars T. Kyllingstad wrote:the relevant functions also be in the stdlib?On Tuesday, 8 May 2012 at 16:35:05 UTC, foobar wrote:On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:[...], what if I find it useful to use e.g. FORTRAN code, should =hand, does. Both druntime and Phobos depend heavily on the C stdlib. = The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc.=20 No, FORTRAN has absolutely nothing to do with D. C, on the other =That doesn't mean its API needs to include Klingon as well. That's = called "encapsulation".=20 -Lars=20 Irrelevant. For all I care druntime could be implemented in Klingon. =just want them to be private so you aren't tempted to use them in your = own code?=20 Um... so you don't mind the C/POSIX declarations being there, you ==20 Yes, pretty much. They are an implementation detail of druntime/phobos. =20 Other vendors may choose to implement the tool-chain with another =language in mind and as long as the API remains the same I shouldn't = need to care e.g. how the GC allocation is implemented (Perhaps it's = done with FORTRAN's memory allocation routines).=20 If I ,the user, want to interface with C I need to use the "official" =C headers in Deimos. This is after all the official location for that. I think this is two separate issues. The GC implementation is very much = hidden already. The only point of exposure for standard C headers is in = core.*, and frankly, I think the only ones actually used are = core.sys.windows and core.sys.posix (posix admittedly being a superset = of standard C, as stated before).=
May 08 2012
On May 8, 2012, at 9:35 AM, foobar wrote:On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:relevant functions also be in the stdlib?On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:[...], what if I find it useful to use e.g. FORTRAN code, should the =hand, does. Both druntime and Phobos depend heavily on the C stdlib. = The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc.=20 No, FORTRAN has absolutely nothing to do with D. C, on the other ==20 Irrelevant. For all I care druntime could be implemented in Klingon. =That doesn't mean its API needs to include Klingon as well. That's = called "encapsulation". This is difficult to do with the module system. You'd have to = hand-craft .di files with the stdc headers left out to avoid bundling = them in the distro. They could go into core.internal I suppose though.=
May 08 2012
On Tuesday, 8 May 2012 at 21:17:21 UTC, Sean Kelly wrote:On May 8, 2012, at 9:35 AM, foobar wrote:Having an internal package is a good idea. Don did the same for the Math code. More over, the general issue with the module system should be fixed. There was a recent discussion about Andrei's DIP, precisely about addressing this problem.On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:This is difficult to do with the module system. You'd have to hand-craft .di files with the stdc headers left out to avoid bundling them in the distro. They could go into core.internal I suppose though.On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc.
May 08 2012
On Tuesday, May 08, 2012 14:17:14 Sean Kelly wrote:On May 8, 2012, at 9:35 AM, foobar wrote:We've previously discussed having _all_ of the C system call functions from the various OSes that we support being in druntime, and I very much think that that's the right way to go. Phobos and druntime then have whatever they need as for as standard C and system call functions go, and anyone who needs any which aren't wrapped by Phobos in some manner has them available to them. Anyone that doesn't want to use any of those C function directly, doesn't have to, but I don't see any reason to hide them just because someone doesn't want to use them in their code. If the problem is that certain C functions end up getting used a lot when they should have D wrappers of some kind which better encapsulate their functionality, then maybe we add the appropriate wrappers to Phobos. But that's a completely different issue. Hiding the C functions doesn't help us any. It makes sense to make truly internal stuff internal, but the standard C function declarations and OS system functions are _not_ internal to druntime. They're _very_ much external. druntime is just providing them because they're functionality which is core to the system that any D program is running on. - Jonathan M DavisOn Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:This is difficult to do with the module system. You'd have to hand-craft .di files with the stdc headers left out to avoid bundling them in the distro. They could go into core.internal I suppose though.On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?>>No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc.>
May 08 2012
On 08-05-2012 23:31, Jonathan M Davis wrote:On Tuesday, May 08, 2012 14:17:14 Sean Kelly wrote:+1. We have better things to fix.On May 8, 2012, at 9:35 AM, foobar wrote:We've previously discussed having _all_ of the C system call functions from the various OSes that we support being in druntime, and I very much think that that's the right way to go. Phobos and druntime then have whatever they need as for as standard C and system call functions go, and anyone who needs any which aren't wrapped by Phobos in some manner has them available to them. Anyone that doesn't want to use any of those C function directly, doesn't have to, but I don't see any reason to hide them just because someone doesn't want to use them in their code.On Tuesday, 8 May 2012 at 14:59:43 UTC, Lars T. Kyllingstad wrote:This is difficult to do with the module system. You'd have to hand-craft .di files with the stdc headers left out to avoid bundling them in the distro. They could go into core.internal I suppose though.On Tuesday, 8 May 2012 at 14:48:27 UTC, foobar wrote:Irrelevant. For all I care druntime could be implemented in Klingon. That doesn't mean its API needs to include Klingon as well. That's called "encapsulation".[...], what if I find it useful to use e.g. FORTRAN code, should the relevant functions also be in the stdlib?>>No, FORTRAN has absolutely nothing to do with D. C, on the other hand, does. Both druntime and Phobos depend heavily on the C stdlib. The GC uses malloc/free, std.stdio.File is a wrapper around FILE*, etc.>If the problem is that certain C functions end up getting used a lot when they should have D wrappers of some kind which better encapsulate their functionality, then maybe we add the appropriate wrappers to Phobos. But that's a completely different issue. Hiding the C functions doesn't help us any.I do think we could benefit from hiding the (deprecated) std.c.* modules on dlang.org (I posted about this a while back).It makes sense to make truly internal stuff internal, but the standard C function declarations and OS system functions are _not_ internal to druntime. They're _very_ much external. druntime is just providing them because they're functionality which is core to the system that any D program is running on. - Jonathan M Davis-- - Alex
May 08 2012
On May 8, 2012, at 2:31 PM, Jonathan M Davis wrote:=20 We've previously discussed having _all_ of the C system call functions =from=20the various OSes that we support being in druntime, and I very much =think that=20that's the right way to go. Phobos and druntime then have whatever =they need=20as for as standard C and system call functions go, and anyone who =needs any=20which aren't wrapped by Phobos in some manner has them available to =them.=20Anyone that doesn't want to use any of those C function directly, =doesn't have=20to, but I don't see any reason to hide them just because someone =doesn't want=20to use them in their code. =20 If the problem is that certain C functions end up getting used a lot =when they=20should have D wrappers of some kind which better encapsulate their=20 functionality, then maybe we add the appropriate wrappers to Phobos. =But=20that's a completely different issue. Hiding the C functions doesn't =help us=20any.I personally use "import core.stdc" as an indicator that there may be = some feature missing from Phobos. It's easily greppable, and easy to = avoid using the routines. In fact, I think "import core" anything = should be an exceptional case in a typical D application. Everything = exposed in Druntime is for what I'd consider power users. Unsafe = threads, runtime and GC hooks, platform API calls, etc. It's all there = because the higher-level stuff needs it, but is really not intended for = general use.It makes sense to make truly internal stuff internal, but the standard =Cfunction declarations and OS system functions are _not_ internal to =druntime.They're _very_ much external. druntime is just providing them because =they'refunctionality which is core to the system that any D program is =running on. Once upon a time, there was a D runtime library (unrelated to Druntime) = that has no C library dependence at all. It was an interesting idea, = but I don't know that there's any system that D targets which doesn't = support C.=
May 08 2012
On 08-05-2012 23:48, Sean Kelly wrote:On May 8, 2012, at 2:31 PM, Jonathan M Davis wrote:I just hope none of it goes away. I make extensive use of many core.* modules.We've previously discussed having _all_ of the C system call functions from the various OSes that we support being in druntime, and I very much think that that's the right way to go. Phobos and druntime then have whatever they need as for as standard C and system call functions go, and anyone who needs any which aren't wrapped by Phobos in some manner has them available to them. Anyone that doesn't want to use any of those C function directly, doesn't have to, but I don't see any reason to hide them just because someone doesn't want to use them in their code. If the problem is that certain C functions end up getting used a lot when they should have D wrappers of some kind which better encapsulate their functionality, then maybe we add the appropriate wrappers to Phobos. But that's a completely different issue. Hiding the C functions doesn't help us any.I personally use "import core.stdc" as an indicator that there may be some feature missing from Phobos. It's easily greppable, and easy to avoid using the routines. In fact, I think "import core" anything should be an exceptional case in a typical D application. Everything exposed in Druntime is for what I'd consider power users. Unsafe threads, runtime and GC hooks, platform API calls, etc. It's all there because the higher-level stuff needs it, but is really not intended for general use.*Is* there any system that doesn't support C? ;) -- - AlexIt makes sense to make truly internal stuff internal, but the standard C function declarations and OS system functions are _not_ internal to druntime. They're _very_ much external. druntime is just providing them because they're functionality which is core to the system that any D program is running on.Once upon a time, there was a D runtime library (unrelated to Druntime) that has no C library dependence at all. It was an interesting idea, but I don't know that there's any system that D targets which doesn't support C.
May 09 2012
On Wednesday, 9 May 2012 at 08:16:35 UTC, Alex Rønne Petersen wrote:Could you please provide more details about your use-cases? As Sean said, it might indicate missing functionality in Phobos. Keep in mind we were specifically discussing the C APIs which are an external dependency. No one suggests removing the low-level druntime APIs such as GC hooks.I personally use "import core.stdc" as an indicator that there may be some feature missing from Phobos. It's easily greppable, and easy to avoid using the routines. In fact, I think "import core" anything should be an exceptional case in a typical D application. Everything exposed in Druntime is for what I'd consider power users. Unsafe threads, runtime and GC hooks, platform API calls, etc. It's all there because the higher-level stuff needs it, but is really not intended for general use.I just hope none of it goes away. I make extensive use of many core.* modules.It isn't only a question of whether the system supports C or not. There are many considerations when choosing your tool-chain. For instance, the reference implementation of some languages is implemented in ML for its correctness properties. EcmaScript for instance uses ML for the language/runtime. In the JS case, it doesn't necessarily mean your browser will run ML, it just means the highly optimized vendor implementation has an official correct version to compare to. In the D world, we have a few projects that aim to implement a D compiler using D. Why would such a compiler/runtime need to provide C APIs if it's completely written in D?Once upon a time, there was a D runtime library (unrelated to Druntime) that has no C library dependence at all. It was an interesting idea, but I don't know that there's any system that D targets which doesn't support C.*Is* there any system that doesn't support C? ;)
May 09 2012
On 09/05/12 10:16, Alex Rønne Petersen wrote:On 08-05-2012 23:48, Sean Kelly wrote:There are plenty of systems that don't support C99 perfectly.On May 8, 2012, at 2:31 PM, Jonathan M Davis wrote:I just hope none of it goes away. I make extensive use of many core.* modules.We've previously discussed having _all_ of the C system call functions from the various OSes that we support being in druntime, and I very much think that that's the right way to go. Phobos and druntime then have whatever they need as for as standard C and system call functions go, and anyone who needs any which aren't wrapped by Phobos in some manner has them available to them. Anyone that doesn't want to use any of those C function directly, doesn't have to, but I don't see any reason to hide them just because someone doesn't want to use them in their code. If the problem is that certain C functions end up getting used a lot when they should have D wrappers of some kind which better encapsulate their functionality, then maybe we add the appropriate wrappers to Phobos. But that's a completely different issue. Hiding the C functions doesn't help us any.I personally use "import core.stdc" as an indicator that there may be some feature missing from Phobos. It's easily greppable, and easy to avoid using the routines. In fact, I think "import core" anything should be an exceptional case in a typical D application. Everything exposed in Druntime is for what I'd consider power users. Unsafe threads, runtime and GC hooks, platform API calls, etc. It's all there because the higher-level stuff needs it, but is really not intended for general use.*Is* there any system that doesn't support C? ;)It makes sense to make truly internal stuff internal, but the standard C function declarations and OS system functions are _not_ internal to druntime. They're _very_ much external. druntime is just providing them because they're functionality which is core to the system that any D program is running on.Once upon a time, there was a D runtime library (unrelated to Druntime) that has no C library dependence at all. It was an interesting idea, but I don't know that there's any system that D targets which doesn't support C.
May 09 2012
Le 08/05/2012 13:59, foobar a écrit :On Sunday, 6 May 2012 at 22:06:32 UTC, Jonathan M Davis wrote:I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.I have a three main problems with the above: a. C++ is *not* fully source compatible with C, especially the latest C99 conflicts with C++ IIRC. b. D isn't either - there are already semantics changes compared to C, as you said so yourself, e.g. static arrays, default initialization of static floats, etc. c. If this is currently a goal of D it really shouldn't be - it prevents us from fixing design bugs we inherited from C such as implicit numeric coercions. As others said, the only thing that sort-of makes sense is to copy/paste *declarations* and even those are different enough in D that they deserve at least a look over to make sure they are correct. We shouldn't promote this "goal" at all especially given that it isn't even guarantied to be 100% correct in all cases. Really what we should be promoting is the fact that D is _link_ compatible with C and allows you to use existing C code _without_ porting it to D.This argument comes up every once in a while even though AFAIK it is *not* a goal of D and never has been! D does not and *should not* strive to be source compatible with C. We already have C++ for that and it is a horrible idea. D can link with C which allows to use pre-existing C code. we should *not* encourage converting C code to D code at all. Either just link the C code or use D idiomatic code.Then you misunderstand. One of the tenets that D holds to is that any C/C++ code either compiles as valid D code with identical semantics, or it doesn't compile as D code (there are a few minor exceptions - such as static arrays being passed by value - but not many). This means that we can break compatibility with C/C++ and do our own thing for a lot of stuff but that we can't just redefine what stuff does such that it would silently break code when it's ported from C/C++ to D. That approach is _very_ different from C++'s approach where valid C code pretty much _always_ compiles identically in C++ (the fact that C++ added keywords being the only exception that I can think of at the moment), but that doesn't mean that we don't care about code portability from C/C++ to D. There's a huge difference between designing a language such that porting code to it from another language isn't error-prone and making the new language source compatibile. D does the former. C++ does the latter. Being able to port code from C/C++ to D without having to worry about silent breakage _is_ one of D's goals. - Jonathan M Davis
May 08 2012
On Tuesday, 8 May 2012 at 19:00:01 UTC, deadalnix wrote:I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.Unfortunately that is not the case. The stated argument is that compiling C code with a D compiler should either compile exactly the same or produce a compilation error. As discussed, this is _already_ incorrect for some cases, is completely unnecessary since you can link with pre-compiled C code (via a C compiler) _without_ any overhead and this forces us to carry legacy C design flaws. If you talking about ease of understanding "C-like" D, that's already a given because D belongs to the C-family of languages. For that matter, JavaScript also belongs to the same family and is easily understood (if you write C-like code). yet no one expects to be able to copy/paste C code into a JS script and have it working as/is.
May 08 2012
On 5/8/2012 3:36 PM, foobar wrote:On Tuesday, 8 May 2012 at 19:00:01 UTC, deadalnix wrote:Thousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.Unfortunately that is not the case. The stated argument is that compiling C code with a D compiler should either compile exactly the same or produce a compilation error.
May 08 2012
Sean Cavanaugh wrote:On 5/8/2012 3:36 PM, foobar wrote:I wholeheartedly agree that breaking changes are frustrating. But especially this one was needed. What we should provide is a clear path to fix the code. In your case, search and replace using a regular expression like s/(\d+).f/\1.0f/g is the way to fix your code in less than 5 minutes I hope. JensOn Tuesday, 8 May 2012 at 19:00:01 UTC, deadalnix wrote:Thousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.Unfortunately that is not the case. The stated argument is that compiling C code with a D compiler should either compile exactly the same or produce a compilation error.
May 09 2012
On 2012-05-09 02:56, Sean Cavanaugh wrote:Thousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I don't see any point in supporting 31.f as a floating point syntax. -- /Jacob Carlborg
May 09 2012
On 09-05-2012 10:27, Jacob Carlborg wrote:On 2012-05-09 02:56, Sean Cavanaugh wrote:+1. -- - AlexThousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I don't see any point in supporting 31.f as a floating point syntax.
May 11 2012
On 5/8/2012 7:56 PM, Sean Cavanaugh wrote:On 5/8/2012 3:36 PM, foobar wrote:s/CTFE/UFCSOn Tuesday, 8 May 2012 at 19:00:01 UTC, deadalnix wrote:Thousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.Unfortunately that is not the case. The stated argument is that compiling C code with a D compiler should either compile exactly the same or produce a compilation error.
May 08 2012
On 5/8/2012 7:56 PM, Sean Cavanaugh wrote:On 5/8/2012 3:36 PM, foobar wrote:s/CTFE/UFCSOn Tuesday, 8 May 2012 at 19:00:01 UTC, deadalnix wrote:Thousands of my C/C++ floating point constants are broken by the CTFE change since as 'integer'-like float constants 31.f and won't compile anymore, since its trying to do f(31) to them for me now . . .I think that goal is misunderstood. It is aimed at human being, not compiler. If one read D code that look like C, it should be able to understand it easily. I is not supped to compile with 100% exact semantic.Unfortunately that is not the case. The stated argument is that compiling C code with a D compiler should either compile exactly the same or produce a compilation error.
May 08 2012
On Thursday, 3 May 2012 at 22:57:02 UTC, Walter Bright wrote:On 5/3/2012 8:13 AM, Don Clugston wrote:I agree that this is a good enough reason in itself. On top of that, the ANSI C stdlib is a subset of the POSIX API, which is *very* useful to have in druntime. Phobos (and druntime itself, of course), uses it for everything platform-specific. -LarsWell, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it.It's there simply because all the Standard C headers should be represented. It should not get anything that is not in Standard C. Ditto for all the other stuff in core.stdc. It's there to make converting C code to D code easier.
May 08 2012
On 3 May 2012 16:13, Don Clugston <dac nospam.com> wrote:On 03/05/12 16:13, Andrei Alexandrescu wrote:I used core.stdc.math to map GCC builtins to math lib functions. This allows for a lot of potential const folding that the D frontend does not (currently) handle. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 5/3/12 9:55 AM, Don Clugston wrote:Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.On 28/04/12 20:47, Walter Bright wrote:Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse
May 03 2012
On 04-05-2012 02:13, Iain Buclaw wrote:On 3 May 2012 16:13, Don Clugston<dac nospam.com> wrote:Does that play nice with errno? -- - AlexOn 03/05/12 16:13, Andrei Alexandrescu wrote:I used core.stdc.math to map GCC builtins to math lib functions. This allows for a lot of potential const folding that the D frontend does not (currently) handle.On 5/3/12 9:55 AM, Don Clugston wrote:Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math.On 28/04/12 20:47, Walter Bright wrote:Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).Andrei and I had a fun discussion last night about this question. The idea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdouble and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverse
May 03 2012
On 4 May 2012 01:40, Alex R=F8nne Petersen <xtzgzorex gmail.com> wrote:On 04-05-2012 02:13, Iain Buclaw wrote:eOn 3 May 2012 16:13, Don Clugston<dac nospam.com> =A0wrote:On 03/05/12 16:13, Andrei Alexandrescu wrote:On 5/3/12 9:55 AM, Don Clugston wrote:On 28/04/12 20:47, Walter Bright wrote:Andrei and I had a fun discussion last night about this question. Th=eidea was which features in D are redundant and/or do not add significant value? A couple already agreed upon ones are typedef and the cfloat, cdoubl=.Well, they are also used in druntime, in core.stdc.math BTW I *hate* that module, I don't know why it exists. Even worse, it seems to be growing -- people are adding more things to it. Practically everything in there has a better implementation in std.math=Good ones. In fact I even discounted them from this discussion because I'd already considered them gone. Walter agreed that I don't mention them in TDPL, with the intent to have them peter out. One good step right now would be to remove NCEG operators from the online documentation. Later on, we'll consider them an accept-invalid bug :o).and creal types. What's your list?Other ones which were agreed to a long time ago were: * NCEG operators * built-in .sort and .reverseThe default is -fno-errno-math for GDC, so errno is not usually set after calling single math instructions. This allows most functions to be used in pure routines. --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';I used core.stdc.math to map GCC builtins to math lib functions. =A0This allows for a lot of potential const folding that the D frontend does not (currently) handle.Does that play nice with errno?
May 04 2012