Re: dmd 1.049 and 2.034 release
Rainer Schuetze wrote: Hi, the problem is related to a change that was probably done to improve http://d.puremagic.com/issues/show_bug.cgi?id=1170 see my comments there for more details. Yeah, makes sense.
Re: dmd 1.049 and 2.034 release
On 2009-10-13 01:56:11 +0200, Moritz Warning moritzwarn...@web.de said: On Mon, 12 Oct 2009 19:29:06 -0400, Nick Sabalausky wrote: Moritz Warning moritzwarn...@web.de wrote in message news:hb01mo$23g...@digitalmars.com... On Mon, 12 Oct 2009 15:53:28 -0400, Nick Sabalausky wrote: Moritz Warning moritzwarn...@web.de wrote in message news:havc43$9a...@digitalmars.com... On Sun, 11 Oct 2009 21:43:36 -0700, Walter Bright wrote: [..] If you're using tango trunk, then I don't know what the problem is either... It's trunk. Maybe this?: http://www.dsource.org/projects/tango/forums/topic/809 No, this is the first error: /home/mwarning/trunk/build/runtime/../../runtime/common/tango/core/ Thread.d(659): Error: e2ir: cannot cast from tango.core.Thread.Thread to void* /home/mwarning/trunk/build/runtime/../../runtime/common/tango/core/ Thread.d(659): Error: e2ir: cannot cast from tango.core.Thread.Thread to void* Though, these cases work: class Foo{} Foo foo = new Foo(); auto x = cast(void*) foo; A{ void* x(){ return cast(void*)this; } } yet that is a strange error, I was not really able to reduce it, on one side it is clearly a compiler error (it does not allow cast(void*)this which is valid), on the other all smaller cases that I could think of seem to work... submitted it as http://d.puremagic.com/issues/show_bug.cgi?id=3392 Fawzi
Re: some problems in dmd.2.034
zsxxsz wrote: I'll download the new release dmd2.xxx where the new one was released. But when I compile dmd2.xxx, I always encounter the same problem as below: $cd dmd.2.034/dmd2/src/dmd $make -f linux.mak backend/dwarf.c:54:26: ../mars/mars.h: No such file or directory backend/dwarf.c: In function `void dwarf_initfile(const char*)': backend/dwarf.c:447: error: `global' was not declared in this scope make: *** [dwarf.o] Error 1 g++ -m32 -c -Wno-deprecated -D__near= -D__pascal= -fno-exceptions -O2 -Ibackend -Itk -D__I86__=1 -DMARS=1 -DTARGET_LINUX=1 -D_DH backend/dwarf.c In file included from backend/dwarf.c:54: backend/../mars/mars.h:246:25: complex_t.h: No such file or directory make: *** [dwarf.o] Error 1 I have to do as below: $mkdir mars $cp mars.h mars/ $cp complex_t.h mars/ and continue to make -f linux.mak, then the compiling will be finish. The problem appeared in DMD.2.xxx, including DMD.2.034. And then, in DMD.2.034, there is a new problem when compiling druntime as below: $cd dmd.2.034/dmd2/src/druntime/src $ make -f dmd-posix.mak cc -c -m32 -g core/stdc/errno.c core/threadasm.S dmd -d -g -w -nofloat -lib -of../../lib/debug/libdruntime-core.a core/bitop.d core/exception.d core/memory.d core/runtime.d core/thread.d core/vararg.d core/sync/barrier.d core/sync/condition.d core/sync/config.d core/sync/exception.d core/sync/mutex.d core/sync/rwmutex.d core/sync/semaphore.d ../../import/core/stdc/math.d ../../import/core/stdc/stdarg.d ../../import/core/stdc/stdio.d ../../import/core/stdc/wchar_.d ../../import/core/sys/posix/netinet/in_.d ../../import/core/sys/posix/sys/select.d ../../import/core/sys/posix/sys/socket.d ../../import/core/sys/posix/sys/stat.d ../../import/core/sys/posix/sys/wait.d errno.o threadasm.o make[1]: execvp: dmd: Permission denied make[1]: *** [../../lib/debug/libdruntime-core.a] Error 127 make: *** [debug] Error 2 After applying the patch for bug #2908 I get the following errors when building dmd 2 (r204) using g++ 4.2.4 on linux: g++ -m32 -c -Wno-deprecated -D__near= -D__pascal= -fno-exceptions -O2 -Ibackend -Itk -D__I86__=1 -DMARS=1 -DTARGET_LINUX=1 -D_DH backend/gloop.c backend/gloop.c:1762: error: stray '\21' in program backend/gloop.c: In function 'void movelis(elem*, block*, loop*, int*)': backend/gloop.c:1762: error: 'struct elem' has no member named 'E' make: *** [gloop.o] Error 1 Is this just due to my GCC version or should I report a bug? That line does appear to have an odd character in it, thought I may as well check in this thread before reporting though. Robert
Re: dmd 1.049 and 2.034 release
http://www.digitalmars.com/d/2.0/changelog.html The link within Download latest D 2.0 alpha D compiler for Win32 and x86 linux is still pointing to 2.027. Ali
Re: DMD svn and contract inheritance
On Tue, 06 Oct 2009 21:28:58 -0300, Leandro Lucarella wrote: Walter Bright, el 6 de octubre a las 12:07 me escribiste: Robert Clipsham wrote: Walter Bright wrote: Then please go ahead and set it up. What exactly would you like setting up? Currently I'm thinking: * Automated builds of dmd 1 and 2 * Automated builds of druntime, phobos and tango * Automated DStress runs * Automated dmd test suite runs (if you're willing to provide me access to the test suite) * Automated builds of more popular projects from dsource (with permission from the maintainers obviously) Is there anything else you want? I also need to know how you would like results to be reported. Would you like them to sit on a web page with an RSS feed, email the results to a specified list of email addresses, post to the nextgroups, post to IRC? I suggest setting it up to email the maintainers of the packages being compiled any problems with compiling them. I think it would be best to have a newsgroup/mailing list/RSS for this. At least being able to see the result in a website. I'm very curious, I'd love to be able to see the results of this automated tests =) A website would be my personal favorite. It's open to everyone and don't spam the mail folder in times of broken code.
Re: dmd 1.049 and 2.034 release
Walter Bright, el 13 de octubre a las 14:16 me escribiste: Rainer Schuetze wrote: Hi, the problem is related to a change that was probably done to improve http://d.puremagic.com/issues/show_bug.cgi?id=1170 see my comments there for more details. I checked into svn a compiler change folding in your patch. Can you try it out with QtD? Thanks for the small commits :) BTW, unless you're planning to skip DMD 2.035, I think you increased the DMD 2 version accidentally to 2.036 ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Yeah, I'm a great quitter. It's one of the few things I do well. I come from a long line of quitters. My father was a quitter, my grandfather was a quitter... I was raised to give up. -- George Constanza
Re: Revamped concurrency API
Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. I did some googling but I only landed on a religious page :/ I assume it means 'temporary shared' just like const is 'temporary immutable', but if i can make a link with the english language too its even better.
Re: Revamped concurrency API
On 2009-10-13 03:17:13 +0200, Robert Jacques sandf...@jhu.edu said: On Mon, 12 Oct 2009 18:21:37 -0400, Fawzi Mohamed fmoha...@mac.com wrote: If anyone has ideas, suggestions, and code to help defining a new concurrency API for D, please post. I think that the correct way to handle concurrency is through a library, D is flexible enough, so that a library can be used, and then one can even write special handlers for special cases. In blip (http://dsource.org/project/blip) I actually did exactly that, in D 1.0 for two reasons: [snip] Looks very interesting. ( Corrected link: http://www.dsource.org/projects/blip ) It looks like it's under the Apache 2.0 license? Would you be willing to put it under the boost license, so that it might be considered for Phobos? if there is interest, yes
Re: Revamped concurrency API
bearophile wrote: Jeremie Pelletier: I vote for a 'lent' qualifier to be implemented in the compiler. You may be right, and Bartosz has explained me why and how to use lent. It sounds like a nice idea, but it has some costs too (in language complexity, for example). But I need to use such things in practice, in real (even small) programs to know/understand if I like and understand them enough. I don't see how heavy that cost is since all of const/immutable/lent/shared are type qualifiers, the semantics are already there for const and immutable, and half there for shared. I would also much prefer compiler implementations to be a bit more complex and implement lent/shared properly than push that complexity to user code. If we're trying to get rid of data races and deadlocks and whatnot, the last thing we want are complex implementations in library/user code because they lack the proper language primitives. If we have just those two qualifiers, the rest of the concurrent models can be implemented entirely in the library. So I'd like to have an experimental version of D where such ideas (like lend, nonnull references, and few other things) can be tried, and if they are experimentally seen as not good (by me too), they can be discarded and removed. For me this is true for nonnull references, but such experimental need is even strong for lend. D2 is already 'experimental' if you consider the state of shared right now :) It seem all the long discussion regarding nonnull references has gone nowhere. That has made me a little sad. Only a bit of flow analysis has being accepted, to cover certain cases of a specific bug case of uninitialized objects. I never liked the Object vs Object? syntax, that would just create ambiguity with the ternary conditional. D already dropped the template syntax from C++ to drop the ambiguity with and comparison operators. I wouldn't mind something like nonnull(Object), ie yet another type qualifier, although that would get cumbersome in a few cases like const(shared(nonnull(Object))) :o) Bye, bearophile
Re: Revamped concurrency API
On Tue, 13 Oct 2009 01:59:57 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. I did some googling but I only landed on a religious page :/ I assume it means 'temporary shared' just like const is 'temporary immutable', but if i can make a link with the english language too its even better. Oh. Yes Lent is a religious holiday, but it's also simple past tense and past participle of lend. ( From http://en.wiktionary.org/wiki/lent ) Apparently it's based off of lentus from French.
Re: Revamped concurrency API
Jeremie Pelletier wrote: Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. I did some googling but I only landed on a religious page :/ I assume it means 'temporary shared' just like const is 'temporary immutable', but if i can make a link with the english language too its even better. to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Andrei P.S. Beer? Coffee? Marriage? I'll be in Quebec City on Dec 10th and 11th for a talk.
Re: Revamped concurrency API
bearophile wrote: Sean Kelly: For what it's worth, I've been experimenting with message-passing for one leg of the API. I decided to copy the Erlang API because it's very simple and easy to build fancier stuff on top of. You may also want to take a look at how actors are in Scala (I think they are a little different than usual, so I think they even have a different name, something like Agents, or something like that): http://www.scala-lang.org/node/242 Bye, bearophile I really like the actor model, it can scale very well to thousands of concurrent actors, I know the Unreal engine use them for all scriptable entities and can process thousands of them per frame. Bartosz also had an entry about actors: http://bartoszmilewski.wordpress.com/2009/07/16/on-actors-and-casting/ This is definitely one concurrent model I want to see in D.
Re: Revamped concurrency API
Jeremie Pelletier wrote: bearophile wrote: Sean Kelly: For what it's worth, I've been experimenting with message-passing for one leg of the API. I decided to copy the Erlang API because it's very simple and easy to build fancier stuff on top of. You may also want to take a look at how actors are in Scala (I think they are a little different than usual, so I think they even have a different name, something like Agents, or something like that): http://www.scala-lang.org/node/242 Bye, bearophile I really like the actor model, it can scale very well to thousands of concurrent actors, I know the Unreal engine use them for all scriptable entities and can process thousands of them per frame. Bartosz also had an entry about actors: http://bartoszmilewski.wordpress.com/2009/07/16/on-actors-and-casting/ This is definitely one concurrent model I want to see in D. Same here. If anyone would like to start putting together an actor API, that would be great. Andrei
Re: Revamped concurrency API
Fawzi Mohamed wrote: On 2009-10-13 03:17:13 +0200, Robert Jacques sandf...@jhu.edu said: On Mon, 12 Oct 2009 18:21:37 -0400, Fawzi Mohamed fmoha...@mac.com wrote: If anyone has ideas, suggestions, and code to help defining a new concurrency API for D, please post. I think that the correct way to handle concurrency is through a library, D is flexible enough, so that a library can be used, and then one can even write special handlers for special cases. In blip (http://dsource.org/project/blip) I actually did exactly that, in D 1.0 for two reasons: [snip] Looks very interesting. ( Corrected link: http://www.dsource.org/projects/blip ) It looks like it's under the Apache 2.0 license? Would you be willing to put it under the boost license, so that it might be considered for Phobos? if there is interest, yes Thanks. There definitely is. I'll start looking at the lib soon, and I recommend others to do the same. Andrei
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu schrieb: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei I have seen lazy only used in its own show case. In log functions. In Tango too it is used in log functions. I use delegates as function parameters often, but not lazy. This is because I may add parameters and on the caller site, IMO it must be obvious, this expression is not evaluated as others. Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); A related issue with passing arguments, that i think needs a better solution in D are the variadic arg list. No magic param names and the possibility to pass this list - or a slice of it - to another function.
Re: Eliminate assert and lazy from D?
bearophile wrote: Andrei Alexandrescu: This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I refuse that critics about lazy. They know D far less than me. I like lazy as it is now, I use it often. It allows me to simulate (in a not perfect way, but sometimes acceptable) Python list comphrensions that no D dev seems interested in adding (or even understanding why they are useful, it seems) to the D language. I use lazy too, it is sometimes useful. The problem is that lazy is very much an oddball. It's a storage class that actually changes the type of a value. You sometimes need to add parens to get the value of a lazy variable, and sometimes not. It's unclear how lazy works with forwarding and how it interacts with templates. One litmus test is that it's very difficult to explain someone how lazy exactly works. I think it's a bad feature, and within reason we should clean the language of bad features. General note: removing features from a language, making a language more general to allow programmers to implement such feature by themselves, sometimes looks positive. But you must keep in mind that it also has some drawbacks and costs. So you must always balance such costs with such advantages. For example compilation times and compilation memory may grow, the syntax may become a little worse, recovery in case of programmer/syntax mistakes may be a little worse, and error messages may become a little (or a lot) worse. The complexity of the language may increase, so people need a bit more time to learn the language (while learning higher-level built-in features often doesn't require a lot of time). A higher number of low level general features (necessary to manually implement the higher level features that have being removed) make the language more flexible, but this is the kind of flexibility of an amoeba, like Forth Lisp, that despite being very flexible languages with 30-45+ years of life, can become hard to use, quite hard to understand, and so on. Languages that hope to become very widespread have to offer a very well chosen set of features, must not offer too much flexibility, they need a certain amount of rigidity and internal constraints that make them a bit less flexible and nice, but make them fit for teams of programmers to build large programs (see the success of Java/C#, etc). So every time you want to remove a higher-level built-in feature you have to think about those factors too. IMHO what makes a language real hard to learn and use is the presence of misdesigned features. Then I'm not sure what you enjoy. Usually you're all for adding features (hey, you just brought up the switch again! isn't that ironic?) and cleaning up bad parts of the language, and now all of a sudden you wax poetic about this and that and the other, few of which have anything to do with the topic at hand. Next time I'll try a post Let's keep lazy in the language - that's bound to get a better response. Andrei
Re: Eliminate assert and lazy from D?
Frank Benoit wrote: Andrei Alexandrescu schrieb: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei I have seen lazy only used in its own show case. In log functions. In Tango too it is used in log functions. I use delegates as function parameters often, but not lazy. This is because I may add parameters and on the caller site, IMO it must be obvious, this expression is not evaluated as others. Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); std.contracts.enforce also uses it. A related issue with passing arguments, that i think needs a better solution in D are the variadic arg list. No magic param names and the possibility to pass this list - or a slice of it - to another function. I'm hoping that template variadics + arrays of Variant cover all needs. Andrei
Re: Revamped concurrency API
Andrei Alexandrescu wrote: Jeremie Pelletier wrote: Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. I did some googling but I only landed on a religious page :/ I assume it means 'temporary shared' just like const is 'temporary immutable', but if i can make a link with the english language too its even better. to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Thanks! I now make the link, may I then suggest the keyword 'borrow', seems to make more sense to me. Do you speak any french or did you just google that? :o) Andrei P.S. Beer? Coffee? Marriage? I'll be in Quebec City on Dec 10th and 11th for a talk. I will most definitely try to be there, I'd love a beer or a coffee, as for marriage.. you'd need to be female from birth, sorry :) Jeremie
Re: Revamped concurrency API
Andrei Alexandrescu Wrote: MIURA Masahiro wrote: Sean Kelly wrote: void sendmsg(T)( Pid pid, T val ); final void recvmsg(T...)( Pid pid, T ops ); Pid spawn(T)( T fun ); spawn() is pretty limited so far in that it only spawns threads--I'd expect that function to end up with multiple overloads at some point. Interesting. Future spawn() may spawn the thread in a remote CPU that doesn't share the memory. In that case it perhaps helps to limit fun to be pure, and val to be immutable, as in Erlang. D already has pure and transitive const, so the first few steps for the massively-parallel D programs are already completed! :-) That's the plan, except that we weren't thinking of creating remote processes, only sending messages across process and machine boundaries. Here's where notions like value vs. reference and deep cloning become very important. Creating remote threads (maybe not OS-level processes) is certainly possible, and I wouldn't be surprised if we did that at some point, assuming something like spawn() is added. But this would be largely invisible at an API level. Like Andrei, I'm more interested in exploring what types should be allowed within messages, what language and library features are necessary, etc. Restricting messages to only shallow value types is certainly possible, but it's rather limiting. I've also experimented with ways to wrap a shared container in the same sendmsg/recvmsg interface, but haven't decided if it's an idea worth pursuing yet (or whether it can even be done in a sufficiently robust manner). In any case, that seemed like one way to eliminate obvious use of mutexes for accessing shared data.
Re: Revamped concurrency API
On Tue, 13 Oct 2009 02:25:07 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Andrei Alexandrescu wrote: [snip] to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Thanks! I now make the link, may I then suggest the keyword 'borrow', seems to make more sense to me. Borrow is a verb, borrowed would be correct noun (i.e. past tense). A lent object and a borrowed object have practically the same meaning, but one word has half the number of characters.
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu: IMHO what makes a language real hard to learn and use is the presence of misdesigned features. I don't agree, the situation is far more complex; good languages are the result of a fine balance between many opposed needs and constraints. and cleaning up bad parts of the language, and now all of a sudden you wax poetic about this and that and the other, few of which have anything to do with the topic at hand. I was talking about language design in general, it was very in-topic in this thread. I try to help, but often I fail... I am sorry. Next time I'll try a post Let's keep lazy in the language - that's bound to get a better response. Good. Inverting points of view is often positive in discussions. It's one of the bases of dialectics. Bear hugs, bearophile
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu wrote: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei lazy is a great feature of D, although you need some sort of usage convention to not get confused with it. For example, there is no way to tell a parameter is lazy from a function call, you need to look at the prototype. But the same can be said with ref and out too so if you remove lazy you also need to rethink these two. I therefore made myself a simple convention on how I use lazy: if the value is evaluated only once I use lazy, otherwise I use a delegate. This makes it clear from the call context what I'm doing. Sometimes I use lazy for values evaluated multiple times (I did it in the json module i posted to D.announce) when the method is private because I'm too lazy (pun intended) to write a full delegate. Jeremie
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu schrieb: Frank Benoit wrote: Andrei Alexandrescu schrieb: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei I have seen lazy only used in its own show case. In log functions. In Tango too it is used in log functions. I use delegates as function parameters often, but not lazy. This is because I may add parameters and on the caller site, IMO it must be obvious, this expression is not evaluated as others. Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); std.contracts.enforce also uses it. Yes, this is, both are functions that try to help the programmer itself and are part of the infrastructure. But is lazy useful for e.g. user libs? Is it useful in an API the user is not fully aware of? I mean if you call a function and you did not know the argument is lazy, it may have strange effects. This is why i would avoid lazy. I think the callers code should have the noticeable different syntax, and we already have that with the curly braces. A related issue with passing arguments, that i think needs a better solution in D are the variadic arg list. No magic param names and the possibility to pass this list - or a slice of it - to another function. I'm hoping that template variadics + arrays of Variant cover all needs. Doesn't that mean, each call with different arguments will instantiate another template instance?
Re: Revamped concurrency API
Robert Jacques wrote: On Tue, 13 Oct 2009 02:25:07 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Andrei Alexandrescu wrote: [snip] to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Thanks! I now make the link, may I then suggest the keyword 'borrow', seems to make more sense to me. Borrow is a verb, borrowed would be correct noun (i.e. past tense). A lent object and a borrowed object have practically the same meaning, but one word has half the number of characters. I disagree that they have the same meaning, one side lends the object and the other borrows it :) But I agree that it makes more sense after reading what you said, maybe I just don't like the sound of past tense verbs in programming keywords, are there any other such keywords in D? Isn't there a qualifier name that would means lent or borrowed without being past-tense, without being a verb implying it also is a function (such as assert). Jeremie
Re: Eliminate assert and lazy from D?
Jeremie Pelletier schrieb: For example, there is no way to tell a parameter is lazy from a function call, you need to look at the prototype. But the same can be said with ref and out too so if you remove lazy you also need to rethink these two. ref and out are not the same category of weirdness for the caller. the compiler will tell that a lvalue is needed for ref and out. But the expression may have side effects, evaluating never/once/multiple is easy to hide errors. I therefore made myself a simple convention on how I use lazy: if the value is evaluated only once I use lazy, otherwise I use a delegate. This makes it clear from the call context what I'm doing. If it is evaluated exactly once, you do not need lazy at all. And if it may also not be evaluated, the callers code is not less safe as when evaluated multiple times.
Re: Revamped concurrency API
On 2009-10-13 07:45:41 +0200, Andrei Alexandrescu seewebsiteforem...@erdani.org said: MIURA Masahiro wrote: Sean Kelly wrote: void sendmsg(T)( Pid pid, T val ); final void recvmsg(T...)( Pid pid, T ops ); Pid spawn(T)( T fun ); spawn() is pretty limited so far in that it only spawns threads--I'd expect that function to end up with multiple overloads at some point. Interesting. Future spawn() may spawn the thread in a remote CPU that doesn't share the memory. In that case it perhaps helps to limit fun to be pure, and val to be immutable, as in Erlang. D already has pure and transitive const, so the first few steps for the massively-parallel D programs are already completed! :-) That's the plan, except that we weren't thinking of creating remote processes, only sending messages across process and machine boundaries. Here's where notions like value vs. reference and deep cloning become very important. Andrei I think that there are different parallelization levels, and different strategies, there isn't ne that rules them all. I am very suspicious of systems where data is moved around magically, normally the cost of that cannot be ignored, so for coarse level parallelization the message passing approach with explicit data distribution done by the programmer is the way to go. On Numa, or really well connected machines having some kind of shared memory is an option, this works well especially if the data is immutable. Finally when one really has shared memory one can go to task scheduling without thinking too much about transfer of memory, it is this last thing that I did address in my previous post. I think that threads are the wrong approach to parallelization at that level, so what I did was to create Tasks that one can use to express more complex relationships between them, so that one can avoids locks almost always, which is both more efficient and less error prone. Fawzi
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu Wrote: Usually you're all for adding features (hey, you just brought up the switch again! isn't that ironic?) and cleaning up bad parts of the language, Sorry, I'm not a computer scientist, and surely I am not a language designer (especially for a C++-class language), so you may see some contradictions in what I sometimes say :-) I have brought up the switch again because I was nervous, after spending some time to find a bug caused by the current design of the switch. There are classes of bugs that aren't easy to avoid, but I think with a less bug-prone switch I may avoid bugs like the one I have removed from my code. One of the most basic part of the Zen of D is to help programmers to avoid bugs, where possible. I hate the idea of having 3 different switches in the language (that's why I was not happy to see the static switch, because a better redesign of the *second* switch was in order). But the current situation of switch is not good for D yet. Bye, bearophile
Re: dmd support for IDEs
On 13/10/2009 07:07, Walter Bright wrote: Yigal Chripun wrote: regarding working on a remote machine: you can mount a remote file system through ssh and work localy on that remoted filesystem. I do that sometimes, but it's a problem when trying to run the compiler/debugger, as they need to run on the remote machine, not just locally g. Eclipse has integration for that. it can execute remote commands and has remote debugging - the local eclipse debugger UI speaks with a remote gdb session. and if you really prefer command-line, you can always use the terminal view. Also, mounting a remote filesystem fails on Windows. I know, that really sux. At least putty works. this requires a 3rd party tool on windows. iirc, WebDrive is free, and for 30$ you can get sftpDrive. (10 years ago, I wired up every room in the house with two RG6 cables and two Cat5 cables while it was under construction. Did it myself because the electrical contractor had no idea how to handle high frequency wires, I had to rip all his stuff out and do it over. I had no use for it at the time. I'm sure glad now it was done, everything I have seems to want to plug in to it! Anyhow, I have several machines with different OSs on them on the lan, and ssh to run them from a central location.)
Re: Revamped concurrency API
Andrei Alexandrescu wrote: MIURA Masahiro wrote: Sean Kelly wrote: void sendmsg(T)( Pid pid, T val ); final void recvmsg(T...)( Pid pid, T ops ); Pid spawn(T)( T fun ); spawn() is pretty limited so far in that it only spawns threads--I'd expect that function to end up with multiple overloads at some point. Interesting. Future spawn() may spawn the thread in a remote CPU that doesn't share the memory. In that case it perhaps helps to limit fun to be pure, and val to be immutable, as in Erlang. D already has pure and transitive const, so the first few steps for the massively-parallel D programs are already completed! :-) That's the plan, except that we weren't thinking of creating remote processes, only sending messages across process and machine boundaries. Here's where notions like value vs. reference and deep cloning become very important. Andrei With the popularity of cloud computing today and applications pushing toward a client frontend to a server backend, it would only be logical to access server threads from clients. I can see many uses of such a model, for example a cloud IDE that reads from and saves to a specialized version control server, showing what other devs are working on in realtime and being notified instantly of their changes, just like google docs do. That's why I keep saying we need multiple concurrent models in D, there are many usages to every single one of them, and if they can all live together its even better. Jeremie
Re: Revamped concurrency API
On Tue, 13 Oct 2009 02:50:41 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Robert Jacques wrote: On Tue, 13 Oct 2009 02:25:07 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Andrei Alexandrescu wrote: [snip] to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Thanks! I now make the link, may I then suggest the keyword 'borrow', seems to make more sense to me. Borrow is a verb, borrowed would be correct noun (i.e. past tense). A lent object and a borrowed object have practically the same meaning, but one word has half the number of characters. I disagree that they have the same meaning, one side lends the object and the other borrows it :) But I agree that it makes more sense after reading what you said, maybe I just don't like the sound of past tense verbs in programming keywords, are there any other such keywords in D? shared? Isn't there a qualifier name that would means lent or borrowed without being past-tense, without being a verb implying it also is a function (such as assert). Jeremie
Re: Revamped concurrency API
Fawzi Mohamed wrote: On 2009-10-13 07:45:41 +0200, Andrei Alexandrescu seewebsiteforem...@erdani.org said: MIURA Masahiro wrote: Sean Kelly wrote: void sendmsg(T)( Pid pid, T val ); final void recvmsg(T...)( Pid pid, T ops ); Pid spawn(T)( T fun ); spawn() is pretty limited so far in that it only spawns threads--I'd expect that function to end up with multiple overloads at some point. Interesting. Future spawn() may spawn the thread in a remote CPU that doesn't share the memory. In that case it perhaps helps to limit fun to be pure, and val to be immutable, as in Erlang. D already has pure and transitive const, so the first few steps for the massively-parallel D programs are already completed! :-) That's the plan, except that we weren't thinking of creating remote processes, only sending messages across process and machine boundaries. Here's where notions like value vs. reference and deep cloning become very important. Andrei I think that there are different parallelization levels, and different strategies, there isn't ne that rules them all. I am very suspicious of systems where data is moved around magically, normally the cost of that cannot be ignored, so for coarse level parallelization the message passing approach with explicit data distribution done by the programmer is the way to go. On Numa, or really well connected machines having some kind of shared memory is an option, this works well especially if the data is immutable. Finally when one really has shared memory one can go to task scheduling without thinking too much about transfer of memory, it is this last thing that I did address in my previous post. I think that threads are the wrong approach to parallelization at that level, so what I did was to create Tasks that one can use to express more complex relationships between them, so that one can avoids locks almost always, which is both more efficient and less error prone. I also don't believe one model is ruling them all. I agree that threads aren't the best approach, even things like async I/O can be done with futures, other operations can be done with async methods, the actor model is perfect for lots of independent operations that can be executed in any order, message passing is great for event driven designs such as GUIs, software transactional memory works great with state management, and those are only a few models. Threads only need a platform abstraction in the library, from which all other concurrency models can be built. Jeremie
Re: Specializing on Compile Time Constants
dsimcha wrote: I'm working on a mathematical expression interpreter for D, which would allow for closed form mathematical expressions to be specified as string literals at runtime and be evaluated. For example: MathExp myExpression = mathExp(x^2 + e^cos(-x) - 2 * sqrt(pi), x); writeln(myExpression(2)); // Does exactly what you think it does. I've found the syntax so convenient that I'd like to transparently specialize it on strings known at compile time. The idea is that, when the expression is hard-coded, you will still be able to use the MathExp interface, but your expression will evaluate at the full speed of a statically compiled function. This is *so* cool. :) -Lars
Re: Revamped concurrency API
Robert Jacques wrote: On Tue, 13 Oct 2009 02:50:41 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Robert Jacques wrote: On Tue, 13 Oct 2009 02:25:07 -0400, Jeremie Pelletier jerem...@gmail.com wrote: Andrei Alexandrescu wrote: [snip] to lend loan lending are all of the same root. lent is the passive/simple past/past participle form of to lend. I guess is the French word is one of confer\'e or pr\^et\'e. Thanks! I now make the link, may I then suggest the keyword 'borrow', seems to make more sense to me. Borrow is a verb, borrowed would be correct noun (i.e. past tense). A lent object and a borrowed object have practically the same meaning, but one word has half the number of characters. I disagree that they have the same meaning, one side lends the object and the other borrows it :) But I agree that it makes more sense after reading what you said, maybe I just don't like the sound of past tense verbs in programming keywords, are there any other such keywords in D? shared? I stand corrected :x
Re: Specializing on Compile Time Constants
On 2009-10-13 09:11:08 +0200, Lars T. Kyllingstad pub...@kyllingen.nospamnet said: I may be wrong, but I seem to remember reading somewhere that DMD always tries to evaluate as much as possible at compile time. That is, if a function is CTFE-enabled, and its input is known at compile time, it is calculated at compile time. void main(string[] args) { auto x = foo(args[1]); // foo() is evaluated at run time auto y = bar(baz);// foo() is evaluated at compile time } you are wrong, compile time evaluation is not performed if not requested (by making that constant for example). The compiler cannot know the complexity of the calculation, and making it at compile time is much slower... thus you have to explicitly instruct the computer to do it...
Re: dmd support for IDEs
Walter Bright wrote: Bill Baxter wrote: That could be true, but you said the thing that prompted this idea was enterprise-y customers looking for an enterprise-y IDE. Vim ain't on that roster. This thread makes it fairly clear that this idea won't fill the bill for a full featured IDE. But I think supporting a lightweight one is still getting us closer. I completely agree, nobody will code a monster IDE like Eclipse or Visual Studio dedicated to D anytime soon. I have only respect for Descent, I use it on linux and it is really great. But Eclipse is killing me, there is no reason for an IDE to be that heavy, slow and unresponsive. How come a database server can pull off any data query from a multi-gigabyte database on disk in half a millisecond yet Eclipse can't seem to feel responsive when working with less than a hundred megabytes in system memory. (On that note, D needs a b-tree module among others :x) I really feel we need a dedicated D IDE to promote the language, and such an IDE needs to start somewhere, most only do syntax highlighting so far, which is trivial to implement. A compiler interface to at least get semantics information from the source files is therefore a *big* plus in that direction. XML output can also be used in so many different ways, for documentation, bindings, analysis and more. And JSON output can be used directly from any language with a very lightweight parser. Besides, this doesn't mean Walter is going to put everything on hold to implement this feature, I think he only wanted to get feedback on an idea he had so when he gets time to implement it, he knows what the community wants. Jeremie
Re: Specializing on Compile Time Constants
dsimcha wrote: == Quote from Jacob Carlborg (d...@me.com)'s article On 10/12/09 23:49, dsimcha wrote: I'm working on a mathematical expression interpreter for D, which would allow for closed form mathematical expressions to be specified as string literals at runtime and be evaluated. For example: MathExp myExpression = mathExp(x^2 + e^cos(-x) - 2 * sqrt(pi), x); writeln(myExpression(2)); // Does exactly what you think it does. I've found the syntax so convenient that I'd like to transparently specialize it on strings known at compile time. The idea is that, when the expression is hard-coded, you will still be able to use the MathExp interface, but your expression will evaluate at the full speed of a statically compiled function. Is there any way to test whether the value of an argument to a template function is known at compile time and specialize on this? Doesn't all values to a template have to be known at compile time No, I mean the *function* parameters of a template function. I may be wrong, but I seem to remember reading somewhere that DMD always tries to evaluate as much as possible at compile time. That is, if a function is CTFE-enabled, and its input is known at compile time, it is calculated at compile time. void main(string[] args) { auto x = foo(args[1]); // foo() is evaluated at run time auto y = bar(baz);// foo() is evaluated at compile time } That said, I also seem to remember that the use of structs and classes is very limited (or nonexistent) in CTFE, and I guess your mathExp() is supposed to return a MathExp struct... -Lars
Re: Revamped concurrency API
Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models.
Re: dmd support for IDEs
Hello Ary, Don wrote: Ary Borenszweig wrote: Michal Minich wrote somewhere else: --- You can try to download just bare Eclipse platform (which is just text editor) and install descent into it using Eclipse software updates. It starts up faster than C or Java version Eclipse and there is only D related stuff in the UI. http://download.eclipse.org/eclipse/downloads/drops/R-3.5.1-20090917 0800/index.php Under Platform runtime binary --- I tried it and it's true, it feels much lighter this way and you don't a lot of bloat in menus and other things. It would be great to put this on the Descent front page. I put it on the Installing the plugin page as soon as I saw it here. Thanks Michal Minich! You are welcome :) I use it this way from the beginning on both Windows and Ubuntu. I first installed Descent into Java Eclipse, but it was also first time I saw Java and Eclipse :) so I was quite overwhelmed by the lot functionality available and could not find which is for D and which for Java. This way it is more beginner friendly. Thank you for your hard work on Descent.
Re: dmd support for IDEs
language_fan wrote: Practical languages have lots of boiler-plate, and I can easily generate hundreds of lines of code with a couple of key combinations or mouse clicks. Can you give some examples? I can only think of some that generate some lines of code, not hundreds.
Re: Eliminate assert and lazy from D?
On 10/13/09 08:21, Andrei Alexandrescu wrote: Frank Benoit wrote: Andrei Alexandrescu schrieb: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei I have seen lazy only used in its own show case. In log functions. In Tango too it is used in log functions. I use delegates as function parameters often, but not lazy. This is because I may add parameters and on the caller site, IMO it must be obvious, this expression is not evaluated as others. Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); std.contracts.enforce also uses it. A related issue with passing arguments, that i think needs a better solution in D are the variadic arg list. No magic param names and the possibility to pass this list - or a slice of it - to another function. I'm hoping that template variadics + arrays of Variant cover all needs. Andrei Templates don't work as virtual methods. Arrays of variants will probably not interact well with C variadic functions.
Re: opXAssign overloading
Robert Jacques wrote: On Tue, 13 Oct 2009 00:31:32 -0400, dsimcha dsim...@yahoo.com wrote: It seems that D's operator overloading is a bit silly in some cases w.r.t. opAddAssign, opSubAssign, etc. Consider the following example: struct Foo { Foo opAdd(Foo rhs) { return this; } } void main() { Foo foo; Foo bar; foo = foo + bar; // Works. foo += bar; // Doesn't work. } I'm thinking (not sure if this was proposed here before a while back and I just forgot where I heard it from) that the default behavior of someObject.opXAssign(otherStuff); should be to expand into someObject = someObject.opX(otherStuff); if opXAssign is not overloaded. Besides the programmer being too lazy to explicitly overload opXAssign, I just found another use case. Suppose you have a bunch of classes and you're overloading operators such that each call builds another layer of decorators. For example: class SomeClass { SomeClass opAdd(SomeClass rhs) { // SomeDecorator is a subclass of SomeClass. return new SomeDecorator(this, rhs); } } In this case, you *can't* overload SomeClass.opAddAssign in any reasonable way because you can't assign SomeDecorator to this, but translating someInstance.opAddAssign(someOtherInstance) into someInstance = someInstance.opAdd(someOtherInstance) makes perfect sense. Also, if you template both opX and opX_r you will always get a overload conflict. Yes, I posted a patch for that to the ng. It's very simple. There has been some discussion as to whether arithmetic operator overloading makes sense at all for reference types. My feeling is that if x = x + y; has a different meaning to x += y; then operator overloading doesn't make sense. But, perhaps with the decorator idea you are close to having a use case for classes where operator overloading makes sense?
Re: Revamped concurrency API
Jeremie Pelletier wrote: bearophile wrote: Jeremie Pelletier: I vote for a 'lent' qualifier to be implemented in the compiler. You may be right, and Bartosz has explained me why and how to use lent. It sounds like a nice idea, but it has some costs too (in language complexity, for example). But I need to use such things in practice, in real (even small) programs to know/understand if I like and understand them enough. I don't see how heavy that cost is since all of const/immutable/lent/shared are type qualifiers, the semantics are already there for const and immutable, and half there for shared. I would also much prefer compiler implementations to be a bit more complex and implement lent/shared properly than push that complexity to user code. If we're trying to get rid of data races and deadlocks and whatnot, the last thing we want are complex implementations in library/user code because they lack the proper language primitives. If we have just those two qualifiers, the rest of the concurrent models can be implemented entirely in the library. So I'd like to have an experimental version of D where such ideas (like lend, nonnull references, and few other things) can be tried, and if they are experimentally seen as not good (by me too), they can be discarded and removed. For me this is true for nonnull references, but such experimental need is even strong for lend. D2 is already 'experimental' if you consider the state of shared right now :) It seem all the long discussion regarding nonnull references has gone nowhere. That has made me a little sad. Only a bit of flow analysis has being accepted, to cover certain cases of a specific bug case of uninitialized objects. I never liked the Object vs Object? syntax, that would just create ambiguity with the ternary conditional. We tried really hard to find a situation that was ambiguous, but without success. I think it's OK. D already dropped the template syntax from C++ to drop the ambiguity with and comparison operators. I wouldn't mind something like nonnull(Object), ie yet another type qualifier, although that would get cumbersome in a few cases like const(shared(nonnull(Object))) :o) Bye, bearophile
Re: Revamped concurrency API
On Tue, 13 Oct 2009 10:10:31 +0400, Jeremie Pelletier jerem...@gmail.com wrote: I never liked the Object vs Object? syntax, that would just create ambiguity with the ternary conditional. D already dropped the template syntax from C++ to drop the ambiguity with and comparison operators. С# uses this syntax, and there is no ambiguity.
Re: A safer switch?
Andrei Alexandrescu Wrote: grauzone wrote: If you still don't like it, you can do some ugly mixin() and CTFE stuff. Nobody will mind because that's modern D style. import std.getopt; void main(string[] args) { getopt(args, s, { writefln(handle argument -s); }, -m, { writefln(handle argument -m); }); ... } What's even better, modern D style allows you to work around some misdesigned/legacy language features.
Re: dmd support for IDEs
Walter Bright Wrote: What do you think? moving ddoc to xml will also fix bug 2060
Re: Eliminate assert and lazy from D?
Frank Benoit Wrote: Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); I second this :) http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=97504
Re: Eliminate assert and lazy from D?
On 2009-10-13 02:44:52 -0400, Frank Benoit keinfarb...@googlemail.com said: I mean if you call a function and you did not know the argument is lazy, it may have strange effects. This is why i would avoid lazy. I think the callers code should have the noticeable different syntax, and we already have that with the curly braces. Hum, side effects... I'm thinking lazy makes more sense if it was forcing the expression to be pure. With provably no side effects, this would make lazy a good optimization technique you can opt-in whenever you need to. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu Wrote: It's simpler actually: debug void assert(T)( T expr, string delegate() msg ) { if(!expr) throw new Exception(msg); } else void assert(T)( T delegate(), string delegate() ) { } Hm, actually it's more complicated than your version :o). Andrei You should be throwing AssertError I really like lazy for log messages and asserts. I like the implicit cast to (scope) pure delegate idea. It works well in those contexts. How hard would it be to use a library assert in ctfe context?
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu wrote: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei assert: should remain. It is important to the compiler. I can easily imagine it participating in range checking. uint x = whatever(); assert(x100); ubyte b = x; // This implicit conversion is OK; we know x is in the appropriate range. lazy: should be removed. It seems to me that 'lazy' covers just a single use case for macros.
Re: Eliminate assert and lazy from D?
Kagamin Wrote: Frank Benoit Wrote: Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); I second this :) http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=97504 I third this. The above article raises a valid observation which needs, uhm well, ..., observing. Why disguise Smiths with Jones? Better to work out a briefer syntax for lambda and half-lambdas. Now for a way out idea, since D source is cognisant of Unicode, albeit UTF-8, why not make use of (U+03BB), Greek Small Letter Lambda in the language? http://www.fileformat.info/info/unicode/char/03bb/index.htm (not the best reference but it will do) Of course this idea is not original, see following for prior art http://community.schemewiki.org/?syntax-unicode-lambda Bests to all, Justin Johansson
Re: dmd support for IDEs
Ary Borenszweig wrote: language_fan wrote: Practical languages have lots of boiler-plate, and I can easily generate hundreds of lines of code with a couple of key combinations or mouse clicks. Can you give some examples? I can only think of some that generate some lines of code, not hundreds. linq-to-sql
Re: CTFE vs. traditional metaprogramming
Yigal Chripun wrote: On 12/10/2009 18:45, BCS wrote: Hello Michel, On 2009-10-09 15:49:42 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org said: Thanks! I plan to add more text at the end of the chapter that discusses the opportunities of CTFE. Walter revealed to me that CTFE, particularly now after it's been improved by leaps and bounds by Don and by Walter himself, could obviate a lot of the traditional metaprogramming techniques developed for C++. One question that bugs me is, where do you draw the line? Say there's a metaprogramming problem at hand. How to decide on solving it with CTFE vs. solving it with templates? It would be great to have a simple guideline that puts in contrast the pluses and minuses of the two approaches. It is quite possible that templates get relegated to parameterized functions and types, whereas all heavy lifting in metaprogramming should be carried with CTFE. My idea on templates is that they're good when you have type parameters, or to create types based on constant parameters. - - - But an interesting thing I realized in the last few months is this: all you can do with a template you can also do at runtime provided sufficient runtime reflection capabilities. Even creating types! Details follow. I'd like to forward the thought that runtime reflection and type creation is NOT a replacement for the same at compile time just as the compile time version is not a replacement for the run time version. Just to pick two differences: errors are forced to runtime and runtime types can't be inlined. you can have compile-time errors with (static) asserts and you can inline runtime types by way of a smart JITer/VM and run-time profiling. CTFE will get exceptions. Shin already put a patch in Bugzilla to do it in a few special case; it's not included yet, since the intention is for CTFE to support classes, and hence should support general exceptions. OTOH, I think BCS was contrasting detecting errors during development (at compile-time) instead of during deployment (at run-time).
Re: Revamped concurrency API
On 2009-10-13 02:16:30 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org said: P.S. Beer? Coffee? Marriage? I'll be in Quebec City on Dec 10th and 11th for a talk. So you'll be in my city too. :-) How many of us are in Quebec City? -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Revamped concurrency API
Jeremie Pelletier, el 13 de octubre a las 01:59 me escribiste: Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. Woops! Sorry, I understood exactly the opposite from you mail =/ -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Sus discipulos se miraron sin entended hasta que uno preguntose: Peperino, soy Daniel Q. de Olivos tengo 54 años y aún soy virgen. A lo que Peperino respondiole: Si sos ganso, ganso ser. Y lo frotó, y lo curó y lo sanó. A lo que todos dijeron: ¡¡¡Peperino se la come, Peperino se la come!!! -- Peperino Pómoro
Amusing D facts: typesafe variadic arrays are lazy!
Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :)
Re: dmd support for IDEs + network GUI (OT)
Nick Sabalausky wrote: Video game developers don't make multiplayer games by sending a compressed video stream of the fully-rendered frame - they know that would be unusable. Instead, they just send the minimum higher-level information that's actually needed, like PlayerA changed direction 72 degrees (over-simplification, of course). And they send it to a client that'll never insist on crap like interpreted JS or open-for-interpretation standards. And when there's a technology that's inadequate for their needs, like TCP, they make a proper replacement instead of hacking in a half-assed solution on top of the offender, TCP. And it works great even though those programs have visuals that are *far* more complex than a typical GUI app. So why can't a windowing toolkit be extended to do the same? And do so *without* building it on top such warped, crumbling, mis-engineered foundations as (X)HTML, Ajax, etc.? This is generally true, although see OnLive (http://www.onlive.com/). I hear it works better than you'd expect, but don't have much interest in actually trying it.
Re: Eliminate assert and lazy from D?
Don Wrote: assert: should remain. It is important to the compiler. I can easily imagine it participating in range checking. uint x = whatever(); assert(x100); ubyte b = x; // This implicit conversion is OK; we know x is in the appropriate range. how about this? long more=fileLength; ubyte[256] buff; for(; more=buff.length ; more-=buff.length) { //read from file, no breaks } //last read read(file,buff.ptr,more); auto rd=buff[0..more]; //can't cast long to uint
Re: Eliminate assert and lazy from D?
Frank Benoit wrote: Andrei Alexandrescu schrieb: Frank Benoit wrote: Andrei Alexandrescu schrieb: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? Andrei I have seen lazy only used in its own show case. In log functions. In Tango too it is used in log functions. I use delegates as function parameters often, but not lazy. This is because I may add parameters and on the caller site, IMO it must be obvious, this expression is not evaluated as others. Maybe it is acceptable to remove lazy and write logging statements with delegate and the curly braces. log({ bla bla ~info }); std.contracts.enforce also uses it. Yes, this is, both are functions that try to help the programmer itself and are part of the infrastructure. But is lazy useful for e.g. user libs? Is it useful in an API the user is not fully aware of? I mean if you call a function and you did not know the argument is lazy, it may have strange effects. This is why i would avoid lazy. I think the callers code should have the noticeable different syntax, and we already have that with the curly braces. I'm wary about magic capabilities that are reserved only to the core compiler and library. Among other things, one wouldn't be able to write their own logging/enforcement library. Historically, Walter has been prone to magic, but since recently he has started systematically using lowering - implement a higher-level feature by rewriting it in terms of simpler D code. He eliminated wads of code from the compiler that way. Maybe it's just me, but I clearly remember: after my first Pascal class, when I learned that writeln is a special function that takes variadic arguments, my only desire has been to be able to write writeln itself. A related issue with passing arguments, that i think needs a better solution in D are the variadic arg list. No magic param names and the possibility to pass this list - or a slice of it - to another function. I'm hoping that template variadics + arrays of Variant cover all needs. Doesn't that mean, each call with different arguments will instantiate another template instance? The template is small - all it does is pack the arguments. void funImpl(Variant[] args) { ... } void fun(T...)(T args) { return funImpl(variantArray(args)); } Andrei
A possible solution for the opIndexXxxAssign morass
Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei
Re: Revamped concurrency API
MIURA Masahiro wrote: Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models. Absolutely! I agree. We need to attack the beast with everything we have. Andrei
Re: dmd development model.
Leandro Lucarella wrote: The RC can be just a tag in the VCS (I think it would be nicer to have an easily distributable package though, Robert even offered himself to do nightly builds automatically for you, so that shouldn't be a problem if the offer is still open). This is still on my to do list... I've pretty much got what I want working manually now, just gotta find some time to set it up to run automatically. Once it's in place, having smaller commits will really make it more useful as you'll be able to pinpoint the exact changes which caused issues or made improvements.
Re: Amusing D facts: typesafe variadic arrays are lazy!
downs wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Gosh!!! What's happening over here? I even tried this: import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } string fun(string a, string b) { writeln(Concatenating...); return a ~ b; } void main() { Assert(true, fun(O hai thar! , wyda)); Assert(false, fun(O hai thar! , wyda)); } This example only prints Concatenatning... once, meaning that fun is also lazified!!! This is very exciting! The fact that this little anomaly hasn't caused trouble is a good sign it could actually replace lazy! Andrei
Re: Revamped concurrency API
MIURA Masahiro Wrote: Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. Exactly. That's also why I settled on the Erlang-like API instead of something like coroutines. It's possible to build a coroutine API on top of the Erlang API, but not vice-versa. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models. I see core as holding language-essential stuff and close to the metal APIs, and have no inclination of hiding core.thread or core.sync from the user. If someone wants to work at this level and they understand the risks they should be able to. Any higher-level stuff like the message-passing API I proposed would live in Phobos and sit on top of what's in core. I disagree about poor performance though. With unique references or move semantics, a copy of even complex data isn't necessary to ensure that a message is passed safely.
Re: Amusing D facts: typesafe variadic arrays are lazy!
Andrei Alexandrescu wrote: downs wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Gosh!!! What's happening over here? I even tried this: import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } string fun(string a, string b) { writeln(Concatenating...); return a ~ b; } void main() { Assert(true, fun(O hai thar! , wyda)); Assert(false, fun(O hai thar! , wyda)); } This example only prints Concatenatning... once, meaning that fun is also lazified!!! This is very exciting! The fact that this little anomaly hasn't caused trouble is a good sign it could actually replace lazy! Andrei There's a bug report about it, from Sean: bugzilla 1069.
Re: Eliminate assert and lazy from D?
On Tue, 13 Oct 2009 08:21:44 -0400, Jason House jason.james.ho...@gmail.com wrote: Andrei Alexandrescu Wrote: It's simpler actually: debug void assert(T)( T expr, string delegate() msg ) { if(!expr) throw new Exception(msg); } else void assert(T)( T delegate(), string delegate() ) { } Hm, actually it's more complicated than your version :o). Andrei You should be throwing AssertError I really like lazy for log messages and asserts. I like the implicit cast to (scope) pure delegate idea. It works well in those contexts. With macros, this can be solved without lazy. I'd say work on getting macros working, then drop lazy and assert. -Steve
Re: A possible solution for the opIndexXxxAssign morass
Andrei Alexandrescu wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei Well timed. I just wrote this operator overloading proposal, part 1. http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP7 I concentrated on getting the use cases established. The indexing thing was something I didn't have a solution for. BTW we need to deal with slices as well as indexes. I think the way to do this is to make a slice into a type of index.
Re: Revamped concurrency API
On 2009-10-13 11:39:21 -0400, Sean Kelly s...@invisibleduck.org said: I disagree about poor performance though. With unique references or move semantics, a copy of even complex data isn't necessary to ensure that a message is passed safely. Yeah, but for unique reference to be usable you need lent semantics, otherwise you can't make sure you're the unique holder once you call a function to do something with your unique object. Anything that use the reference could be storing it elsewhere: unique!Object o = new Object; o.doSomething(); How in the example above can I enforce that doSomething() won't escape the 'o' reference elsewhere? 'doSomething' could be made 'pure', but that trick will only work for one-argument functions (in the case above, the argument is the implicit 'this') because otherwise a pure function could leak the reference through another argument. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 11:16:01 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) I'm guessing you meant opAssign here, or meant to write +=? What do you think? I may be missing some important cases or threats. It's simple, and gets rid of all opIndex operators except for opIndex itself. The question then becomes, what if you wanted to overload this? a[b][c] += d; You can do a[b] returns a ref. But then you now allow a[b] op x, thereby possibly exposing a private piece of info. This may or may not be important. I like the way your idea is going. -Steve
Re: A possible solution for the opIndexXxxAssign morass
Steven Schveighoffer wrote: On Tue, 13 Oct 2009 11:16:01 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) I'm guessing you meant opAssign here, or meant to write +=? Oh, sorry. I meant to write +=. What do you think? I may be missing some important cases or threats. It's simple, and gets rid of all opIndex operators except for opIndex itself. The question then becomes, what if you wanted to overload this? a[b][c] += d; You can do a[b] returns a ref. But then you now allow a[b] op x, thereby possibly exposing a private piece of info. This may or may not be important. I like the way your idea is going. Great. Indeed the proposed solution leaves a[b][c] += d problematic, and also prevents this potential development: a += b + c + d; to be rewritten as: a.opAddAssign(b, c, d); Andrei
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 19:16:01 +0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei How about this case: a[b1..b2] = c; ? I could be solved if b1..b2 would return some built-in range type, defined in object.d, though.
Re: Revamped concurrency API
On Tue, 13 Oct 2009 11:19:30 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: MIURA Masahiro wrote: Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models. Absolutely! I agree. We need to attack the beast with everything we have. Andrei I'd recommend reading Bartosz's blog on thread objects vs spawn (http://bartoszmilewski.wordpress.com/2009/09/01/spawning-a-thread-the-d-way/). It makes a really good case for why thread objects should never be sub-classed and therefore should be a private, hidden implementation detail and not a public API.
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 12:28:05 -0400, Denis Koroskin 2kor...@gmail.com wrote: On Tue, 13 Oct 2009 19:16:01 +0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei How about this case: a[b1..b2] = c; ? I could be solved if b1..b2 would return some built-in range type, defined in object.d, though. That already has an operator: int opSliceAssign(int v, size_t x, size_t y); a[3..4] = v;// same as a.opSliceAssign(v,3,4);
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 9:08 AM, Steven Schveighoffer schvei...@yahoo.com wrote: On Tue, 13 Oct 2009 11:16:01 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) I'm guessing you meant opAssign here, or meant to write +=? What do you think? I may be missing some important cases or threats. It's simple, and gets rid of all opIndex operators except for opIndex itself. Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. --bb
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 12:21:20 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Steven Schveighoffer wrote: On Tue, 13 Oct 2009 11:16:01 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) I'm guessing you meant opAssign here, or meant to write +=? Oh, sorry. I meant to write +=. What do you think? I may be missing some important cases or threats. It's simple, and gets rid of all opIndex operators except for opIndex itself. The question then becomes, what if you wanted to overload this? a[b][c] += d; You can do a[b] returns a ref. But then you now allow a[b] op x, thereby possibly exposing a private piece of info. This may or may not be important. I like the way your idea is going. Great. Indeed the proposed solution leaves a[b][c] += d problematic, and also prevents this potential development: a += b + c + d; to be rewritten as: a.opAddAssign(b, c, d); Andrei Well, that last case I'd prefer handled by something more generic, like an opExpression(Expr, T...)(T params); (i.e. a way of doing expression template/ BLADE like stuff, without the syntactic or runtime overhead.
Re: Amusing D facts: typesafe variadic arrays are lazy!
On Tue, 13 Oct 2009 15:06:25 +0200, downs default_357-l...@yahoo.de wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Yes, it is documented. Lazy Variadic Functions on Functions page.
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 20:34:06 +0400, Robert Jacques sandf...@jhu.edu wrote: On Tue, 13 Oct 2009 12:28:05 -0400, Denis Koroskin 2kor...@gmail.com wrote: On Tue, 13 Oct 2009 19:16:01 +0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei How about this case: a[b1..b2] = c; ? I could be solved if b1..b2 would return some built-in range type, defined in object.d, though. That already has an operator: int opSliceAssign(int v, size_t x, size_t y); a[3..4] = v;// same as a.opSliceAssign(v,3,4); I meant: a[b1..b2] += c; Another thing I dislike about this proposal is that a[b] += c; translates into opAddAssign and doesn't mention index while a[b] = c; does (opIndexAssign).
Re: A possible solution for the opIndexXxxAssign morass
On 2009-10-13 11:16:01 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org said: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); I'd rewrite it as opIndexAddAssign(b, c); That way you can also rewrite: a[b..c] = d; as opSliceAddAssign(b, c, d); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) That looks like a good idea, although I'd be a little tempted to put the variable-length part at the end so you can easily choose to use variadic arguments. Also noteworthy: none of this work if you want to mix index and slices: a[b, c..d] = f; What do you think? I may be missing some important cases or threats. Wasn't the bigger problem with operator overloading the fact that you have to redefine it for every primitive operator? I seem to recall you arguing for a way to overload all the operators at the same time. Where's that going? -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 12:44:21 -0400, Denis Koroskin 2kor...@gmail.com wrote: Another thing I dislike about this proposal is that a[b] += c; translates into opAddAssign and doesn't mention index while a[b] = c; does (opIndexAssign). I think the optimization translates to opAssign as well: a[b] = c; = a.opAssign(b, c); On Tue, 13 Oct 2009 12:37:50 -0400, Bill Baxter wbax...@gmail.com wrote: Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. The point is to avoid having operator function names multiply out of control. Re-examining it, I agree with you -- It makes little sense to have an operator that involves an indexing lack the term Index. If only there was a way to make the indexing orthogonal to the other operation. For example something like: struct X { private int[] arr; opIndex(int idx) // declares a new namespace where idx is an implicitly passed argument { int opAssign(int x) { arr[idx] = x; return x; } } } I know this probably doesn't parse well, should opIndex be a keyword? or an attribute? -Steve
Re: Revamped concurrency API
Robert Jacques wrote: On Tue, 13 Oct 2009 11:19:30 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: MIURA Masahiro wrote: Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models. Absolutely! I agree. We need to attack the beast with everything we have. Andrei I'd recommend reading Bartosz's blog on thread objects vs spawn (http://bartoszmilewski.wordpress.com/2009/09/01/spawning-a-thread-the-d-way/). It makes a really good case for why thread objects should never be sub-classed and therefore should be a private, hidden implementation detail and not a public API. Threads should NOT be private, I don't mind making them final classes but some programs may not require, or some programmers may not want, the high level constructs. If you put the thread construct in core.thread and the concurrent implementations in std.concurrent you still need the std api to access the core threads. But threads being a core module makes it a here it is should you want it, but check these standard modules first kind of module. Threads being public also allow any programmer to build custom concurrent models if they're not in the library. Jeremie
Re: A possible solution for the opIndexXxxAssign morass
Bill Baxter wrote: Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. --bb That's a good point. But something is inherently problematic about name explosion (In the proposed solution there is still an explosion in the count of functions that need to be written.) Now I realize there's also a need for opSliceXxxAssign, bleh. Unless we ascribe a distinct type to a .. b. Andrei
Re: Amusing D facts: typesafe variadic arrays are lazy!
Max Samukha wrote: On Tue, 13 Oct 2009 15:06:25 +0200, downs default_357-l...@yahoo.de wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Yes, it is documented. Lazy Variadic Functions on Functions page. Awesome. I'll replace the use of lazy in enforce() with that. Andrei
Re: Revamped concurrency API
Robert Jacques wrote: On Tue, 13 Oct 2009 11:19:30 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: MIURA Masahiro wrote: Jeremie Pelletier wrote: I also don't believe one model is ruling them all. Let me clarity this, just in case I have caused an unnecessary confusion: I think Sean's Erlang-like API is meant to coexist with the current core.thread, and that you can use one or both of them to build higher-level concurrency models. I think it's nice to have core.thread *and* message-passing API in Phobos. Thread alone is too primitive for daily use, but we don't want to have too many concurrency models. Absolutely! I agree. We need to attack the beast with everything we have. Andrei I'd recommend reading Bartosz's blog on thread objects vs spawn (http://bartoszmilewski.wordpress.com/2009/09/01/spawning-a-thread-the-d-way/). It makes a really good case for why thread objects should never be sub-classed and therefore should be a private, hidden implementation detail and not a public API. I reviewed that article so I guess I read it :o). Bartosz's position is held by many people in the C++ threading community. Andrei
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 10:00 AM, Steven Schveighoffer schvei...@yahoo.com wrote: On Tue, 13 Oct 2009 12:44:21 -0400, Denis Koroskin 2kor...@gmail.com wrote: Another thing I dislike about this proposal is that a[b] += c; translates into opAddAssign and doesn't mention index while a[b] = c; does (opIndexAssign). I think the optimization translates to opAssign as well: a[b] = c; = a.opAssign(b, c); On Tue, 13 Oct 2009 12:37:50 -0400, Bill Baxter wbax...@gmail.com wrote: Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. The point is to avoid having operator function names multiply out of control. Re-examining it, I agree with you -- It makes little sense to have an operator that involves an indexing lack the term Index. If only there was a way to make the indexing orthogonal to the other operation. For example something like: struct X { private int[] arr; opIndex(int idx) // declares a new namespace where idx is an implicitly passed argument { int opAssign(int x) { arr[idx] = x; return x; } } } I know this probably doesn't parse well, should opIndex be a keyword? or an attribute? I don't think the number of /names/ required is the problem. It's just the sheer number of functions themselves that's the issue. I think a lot of that could mostly be fixed by some smart macros. And until they exist, mixins can help. struct Vec { float x,y,z; mixin(implementOperators(+ - / * += -= /= *=, q{ a.x op= b.x; a.y op= b.y; a.z op= b.z; }); } The code gives a list of operators to implement and one prototypical op= body. With a smart enough CTFE string function that's all you need to generate all the listed operators. Not sure how to work index operators into that. --bb
Re: Eliminate assert and lazy from D?
On Tue, 13 Oct 2009 07:33:57 +0300, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? No one seems to have mentioned this, but please don't overlook that when compiling in release mode, assert (or at least assert(0)) works as a compiler hint. -- Best regards, Vladimir mailto:thecybersha...@gmail.com
Re: Revamped concurrency API
Michel Fortin Wrote: On 2009-10-13 11:39:21 -0400, Sean Kelly s...@invisibleduck.org said: I disagree about poor performance though. With unique references or move semantics, a copy of even complex data isn't necessary to ensure that a message is passed safely. Yeah, but for unique reference to be usable you need lent semantics, otherwise you can't make sure you're the unique holder once you call a function to do something with your unique object. Anything that use the reference could be storing it elsewhere: unique!Object o = new Object; o.doSomething(); How in the example above can I enforce that doSomething() won't escape the 'o' reference elsewhere? 'doSomething' could be made 'pure', but that trick will only work for one-argument functions (in the case above, the argument is the implicit 'this') because otherwise a pure function could leak the reference through another argument. I honestly don't know how to enforce this-- I simply mentioned it because people have suggested it. Phobos already has assumeUnique() for converting to invariant, which is one option. I was hoping someone could suggest alternatives.
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 10:08 AM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Bill Baxter wrote: Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. --bb That's a good point. But something is inherently problematic about name explosion (In the proposed solution there is still an explosion in the count of functions that need to be written.) Now I realize there's also a need for opSliceXxxAssign, bleh. Unless we ascribe a distinct type to a .. b. Yeh, the name explosion is just a symptom of the real problem, which is function count explosion. That's what needs fixing, if anything. But I don't really think having a lot of functions is the issue, it's implementers having to *write* a lot of boring repetitive functions that is the problem. So if the drudgery can be automated somehow (in the cases where the pattern is regular), then that would solve the problem in my mind. Even if it was still a function explosion under the hood. --bb
Re: Amusing D facts: typesafe variadic arrays are lazy!
downs wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Here is a funny consequence of this amusing fact: if you overload opAssign in a struct with lazy T[] dgs..., you can achieve the following syntax WithFlag(GL_BLEND, true) = WithDepthMask(false) = tex.With = Quads = { foreach (i, q; qa) { float f = 1f*i / qa.length; Color(1f-f, f, 1f); TexCoord(0f, 0f); Vertex(q.points[0]); TexCoord(1f, 0f); Vertex(q.points[1]); TexCoord(1f, 1f); Vertex(q.points[3]); TexCoord(0f, 1f); Vertex(q.points[2]); } };
Re: A possible solution for the opIndexXxxAssign morass
This idea along with a slice overload would save me a lot of pain and performance while working with matrices in my production code. Any ideas when this could be implemented in D1? Jonathan Andrei Alexandrescu wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 10:22 AM, JC jcrapuchet...@gmail.com wrote: This idea along with a slice overload would save me a lot of pain and performance while working with matrices in my production code. Any ideas when this could be implemented in D1? Jonathan It won't be implemented in D1. Stability -- it's the beauty and the beast of D1. --bb
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 11:56:36 -0400, Don nos...@nospam.com wrote: Andrei Alexandrescu wrote: Right now we're in trouble with operators: opIndex and opIndexAssign don't seem to be up to snuff because they don't catch operations like a[b] += c; with reasonable expressiveness and efficiency. Last night this idea occurred to me: we could simply use overloading with the existing operator names. Consider: a += b gets rewritten as a.opAddAssign(b) Then how about this - rewrite this: a[b] += c as a.opAddAssign(b, c); There's no chance of ambiguity because the parameter counts are different. Moreover, this scales to multiple indexes: a[b1, b2, ..., bn] = c gets rewritten as a.opAddAssign(b1, b2, ..., bn, c) What do you think? I may be missing some important cases or threats. Andrei Well timed. I just wrote this operator overloading proposal, part 1. http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP7 I concentrated on getting the use cases established. The indexing thing was something I didn't have a solution for. BTW we need to deal with slices as well as indexes. I think the way to do this is to make a slice into a type of index. I've mentioned this problem before, in relation to multi-dimensional arrays: // Slice a row out of an Matrix row0 = myMatrix[0,0..$]; So basically, opIndex and opSlice need to merge to support this use case. I've always ended up doing this with using size_t[2] or size_t[3] (for slicing with strides) when I've coded Nd-arrays, though this is a bit clunky. However, a while ago someone mentioned that tuple, though cool/useful/etc wasn't being used as much (compared to other languages) because of a lack of syntactic sugar. Which gave me the idea of using the .. operator to be syntactic sugar for tuple, as it would solve two birds with one stone. (Maybe three, if you count MVR) Also needed is an extension of the opDollar to return different values based on the index: opDollar(size_t index); P.S. There's also at least one template bug blocking Nd-arrays and small vector types: (http://d.puremagic.com/issues/show_bug.cgi?id=2257). P.S.S. Another template issue is that templating both opX and opX_r generally results in an overload conflict.
Re: A possible solution for the opIndexXxxAssign morass
On Tue, 13 Oct 2009 13:08:59 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Bill Baxter wrote: Huh? It didn't sound to me like it would get rid of anything, except for the use of the word index in many methods that have to do with index operations. That just seems confusing to me. I think the opIndexXxxAssign functions may need to be added, but adding them by overloading existing names doesn't seem a win to me. --bb That's a good point. But something is inherently problematic about name explosion (In the proposed solution there is still an explosion in the count of functions that need to be written.) Now I realize there's also a need for opSliceXxxAssign, bleh. Unless we ascribe a distinct type to a .. b. Andrei A distinct type for a..b is needed to support the mixed slicing and index that occurs in Nd-array/Matrixes: i.e. auto row0 = myMatrix[0,0..$];
Re: A possible solution for the opIndexXxxAssign morass
Forgotten already? http://prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semantic This is the same problem as property lvalue-ness and it has the same solution. When property rewriting is done correctly, the opIndexAssign problem can then be solved almost for free. Just treat opIndex expressions as properties, and when they are the subject of a side-effect then make sure the write property (AKA opIndexAssign) gets called.
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 8:56 AM, Don nos...@nospam.com wrote: Well timed. I just wrote this operator overloading proposal, part 1. http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP7 I concentrated on getting the use cases established. The indexing thing was something I didn't have a solution for. BTW we need to deal with slices as well as indexes. I think the way to do this is to make a slice into a type of index. I think it's a good start. In the list of properties, you should probably mention that 'a' is a scalar. But I wonder how the rules involving scalars could be enforced, given that it's possible to define new scalar types. One would have to tell the compiler somehow which types are scalars relative to the type being defined. The ++ operators don't make sense for many of the types you listed. Maybe that should be broken out. Actually three of the things really stand out as computer-isms that don't really belong with the other mathematical properties: x...@=y == x = x @ y x++ == ++x x...@=y returns x Also, you can add Clifford algebra, Grassmann algebra, and geometric algebra to the list of things where the mathematical properties hold. --bb
Re: A possible solution for the opIndexXxxAssign morass
On Tue, Oct 13, 2009 at 10:39 AM, Chad J chadj...@__spam.is.bad__gmail.com wrote: Forgotten already? Apparently, yes! http://prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semantic This is the same problem as property lvalue-ness and it has the same solution. When property rewriting is done correctly, the opIndexAssign problem can then be solved almost for free. Just treat opIndex expressions as properties, and when they are the subject of a side-effect then make sure the write property (AKA opIndexAssign) gets called. Good call. --bb
Re: Eliminate assert and lazy from D?
On Tue, 13 Oct 2009 00:33:57 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Right now, the language has enough power to express assert as a library function, as opposed to a primitive construct. (See e.g. enforce.) I think it would be good to relegate assert to object.d. This also brings up lazy, which seems to be quite botched. Are there suggestions on how to replicate its functionality in a different way? I even seem to recall lazy was discussed as a disadvantage in the recent dialog on reddit, see http://www.reddit.com/r/programming/comments/9qf8i/i_wrote_some_d_today_and_its_completely_blowing/ I personally believe it's useful to be able to pass an unevaluated expression into a function, for example assert and enforce themselves use that. But let's open this for discussion: should assert and/or lazy be removed? If not, why not? It yes, why? How can we replicate their functionality? How to trigger assert when no -debug or -release flag is set? Is there a flag we can trigger on? From what I understand assert triggers when -debug or no flag is set, but not when -release flag is set. -Steve
Re: Goodbye
Yigal Chripun wrote ego has nothing to do with being smart. you can be extremely smart without getting on people's nerves all the time. A smart person can choose when to get on somebody's nerves ;)
Re: opXAssign overloading
On Tue, Oct 13, 2009 at 2:30 AM, Don nos...@nospam.com wrote: Robert Jacques wrote: On Tue, 13 Oct 2009 00:31:32 -0400, dsimcha dsim...@yahoo.com wrote: It seems that D's operator overloading is a bit silly in some cases w.r.t. opAddAssign, opSubAssign, etc. Consider the following example: struct Foo { Foo opAdd(Foo rhs) { return this; } } void main() { Foo foo; Foo bar; foo = foo + bar; // Works. foo += bar; // Doesn't work. } I'm thinking (not sure if this was proposed here before a while back and I just forgot where I heard it from) that the default behavior of someObject.opXAssign(otherStuff); should be to expand into someObject = someObject.opX(otherStuff); if opXAssign is not overloaded. Besides the programmer being too lazy to explicitly overload opXAssign, I just found another use case. Suppose you have a bunch of classes and you're overloading operators such that each call builds another layer of decorators. For example: class SomeClass { SomeClass opAdd(SomeClass rhs) { // SomeDecorator is a subclass of SomeClass. return new SomeDecorator(this, rhs); } } In this case, you *can't* overload SomeClass.opAddAssign in any reasonable way because you can't assign SomeDecorator to this, but translating someInstance.opAddAssign(someOtherInstance) into someInstance = someInstance.opAdd(someOtherInstance) makes perfect sense. Also, if you template both opX and opX_r you will always get a overload conflict. Yes, I posted a patch for that to the ng. It's very simple. There has been some discussion as to whether arithmetic operator overloading makes sense at all for reference types. My feeling is that if x = x + y; has a different meaning to x += y; then operator overloading doesn't make sense. But, perhaps with the decorator idea you are close to having a use case for classes where operator overloading makes sense? Well, I have implemented an N-d array-like type as a class before. I don't think it's the best way to do it, but someone might like to have a general array class they could override to behave as a matrix. There is such a thing in Numpy. I don't think it's the greatest idea in the world, but if you do make such a thing, then you want to be able to make += identity preserving and = not. And that's how stuff works in Python in general. += modifies an object, = changes its identity.So I wouldn't say it's nonsense to have such a rule. What you can say is that this better be true (to within numerical precision) x1 = x + y x += y == x1 == x --bb x+
Re: Eliminate assert and lazy from D?
Andrei Alexandrescu: Maybe it's just me, but I clearly remember: after my first Pascal class, when I learned that writeln is a special function that takes variadic arguments, my only desire has been to be able to write writeln itself. Have you seen the asm produced by a small console D2 program? Even if you do very little there's a good amount of templates. That's one of the prices you have to pay, I was talking about in the poetic part of my post. Bye, bearophile
Re: Goodbye
Jarrett Billingsley Wrote: I'm done. After seeing how Andrei is behaving, I really am done. Bye. It's what we call in UK 'handbags at 10 paces'.
Re: Array literals' default type
Bill Baxter wrote: foo((1,2)); // um, what? You see that kind of thing in Python all the time, with NumPy at least. Array dimensions for example are set with a tuple. So x = array((1,2), dtype=int) And very common to see things like numpy.zeros((10,20)). This is one place [of many] where you can't say, Oh, leave off the parens and it's a comma exp. That leaves me in the lurch. When offered semantic ambiguity, just say no. You didn't really show any examples of ambiguity that I could see. Some of those examples may have a legal meaning in C, so that's an issue if so. If you try to add tuple expressions AND keep comma expressions, you either can't recurse from paren exp to comma exp (or any exp, really) or you have semantic ambiguity. If you can't recurse comma exps, they're nothing more than semicolons. Worthless, so you might as well remove them. Or you have to introduce a new syntax. aside Actually, making comma exp a little uglier might be an appealing solution. something like CommaExp - , CommaExp CommaExp - AsgExp gives you auto a = (,1,2); // a = 2 auto a = (1,2); // a = (1,2) You still have the problem of ( nonCommaExp ), though. And user-friendliness issues. I'm sure others could think of better ideas.