Re: Game development is worthless? WTF? (Was: Why Ruby?)
On 12/18/10 14:12, Nick Sabalausky wrote: Nick Sabalausky a...@a.a wrote in message news:iej46p$42...@digitalmars.com... Caligo iteronve...@gmail.com wrote in message news:mailman.5.1292651710.4588.digitalmar...@puremagic.com... IMO there is no honor in game development as it contributes nothing to society. I've rarely played any, I gotta jump on this as being a giant load of pretentious bullshit. First of all, there's the patently obvious how in the world would you know? considering the I've rarely played any. But more importantly, games make life suck less - I can't even imagine any more significant contribution to society than that. Even all of the endeavors generally considered to be the biggest contributions to society are *only* significant contributions *because* that's exactly what they do: they make life suck less, and are therefore well-regarded. Seriously, what up with all those presumptuous assholes out there (mostly baby boomer dinos and their even more anachronistic parents, interestingly enough) who have barely ever touched a videogame and yet figure they actually have reason to believe such absurd pretentious crap? Fuck, they all remind me of that pompous Roger Ebert douchebag. (Speaking of ways to benefit society, when's he finally gonna keel over? Isn't it about time by now? And speaking of contributions to society what the fuck's he ever done? Collect a salary just to spout off opinions? Fucking useless wanker.) Since it apparently isn't obvious to some people: things don't have to be dull to qualify as a significant a contribution. There's also the classic example: a game was instrumental in the development of UNIX. http://en.wikipedia.org/wiki/Space_Travel_(video_game) This wasn't arbitrary either; it was something Thompson wanted to do, and he needed a better OS to do it in... so his toy got new polish. Some of this polish became things we now take for granted and hardly know how to live without (like a hierarchial filesystem). Do I mean to say that without the game there would be no UNIX? No; but I do mean to say that games have *always* been a valuable tool for finding the limits of systems, and for inspiring innovative ways to expand those limits. The same research and development that provided pixel shaders to game developers, also provided them to medical imaging developers. The same that provided CPU technologies such as SSE to enable more complex simulations in games, also provide for more complex simulations in supercomputers. And many of these sort of technologies were original conceived just to make games more awesome. Amazing. So no, games in and of themselves don't contribute anything -- if you don't count fun, and honestly, I do count it -- but they have been a driving force behind a lot of innovation. /rant -- Chris N-S
Re: Why Ruby?
On 12/19/10 01:29, spir wrote: On Sat, 18 Dec 2010 18:13:50 -0800 Walter Bright newshou...@digitalmars.com wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. Short, but wrong. I mean conceptually. In-code string representation of code is wrong. I cannot explain why, but something in me refuses that. Seems I'm not the only one. Maybe it's my history with embedded languages with eval() or eval-like functions, like the BASIC one you referenced... or maybe it's because my D brain likens this usage to the very thing that's going on behind the scenes (string mixin), and which has proven to be a very handy feature... I'm not sure what might be the reason, but: I find it suits me fine. I'm not boasting or anything like that; I'm just pointing out that the issues no doubt stem, at least in part, from a difference in individual programmers' experience. I'm used to making valuable use of things like eval() -- which you evidently dislike, and not for invalid reasons. Ultimately, though, I think this whole matter of D lambdas boils down to just plain not liking the use of strings as anything other than self-contained text data snips. One of those weird languages I'm used to had two different kinds of string literal... and the second one was actually a list of explicit character codes, as integers. You'd be surprised the uses one would find for this thing -- such as easily writing escape code sequences. My point? Different language, different environment. When the new environment is drastically different from what we're used to, even if only in a few aspects, we shy from it. At any rate, there's always the MiniD syntax to inspire those who must seek another way. This: func(\a, b - a * b) ...is rewritten as: func(function(a, b) { return a*b; }) Obviously the backslash would be a potential problem. --Chris N-S
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Christopher Nicholson-Sauls: So no, games in and of themselves don't contribute anything -- if you don't count fun, and honestly, I do count it -- but they have been a driving force behind a lot of innovation. Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) Bye, bearophile
Re: Game development is worthless? WTF? (Was: Why Ruby?)
On 12/19/10 04:19, bearophile wrote: Christopher Nicholson-Sauls: So no, games in and of themselves don't contribute anything -- if you don't count fun, and honestly, I do count it -- but they have been a driving force behind a lot of innovation. Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) Bye, bearophile Touché. ;) But I said 'game' not 'cult.' :D -- Chris N-S
Re: Why Ruby?
Walter Bright newshou...@digitalmars.com wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab ? No. But often, you want to call a function in a lambda, in which case the string version croaks. Also, it is not always possible to pass the lambda by template alias parameter, in which case the string version is right out the window. As for functions taking a delegate, the {=@+@;} syntax will not work with overloading or template functions (nor will the other syntaxen that elides types). It could also be that functions taking delegates are or should be rare, and thus not worth optimizing for. -- Simen
Re: Why Ruby?
Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); The bikesheding of the syntax does not address this concern at all.
Re: Why Ruby?
Sun, 19 Dec 2010 06:08:15 -0500, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); The bikesheding of the syntax does not address this concern at all. Two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort) - symbol visibility problems because of wrong scoping
Re: New syntax for string mixins
Nick Sabalausky Wrote: The problem with that is, what if you're generating target-platform-specific code at compile-time? You'd be generating code for the wrong platform. I think VladD2 is right: You need to keep track of both current system and target system. Unfortunately, there is some information about the target system the compile-time code wouldn't be able discern without giving it the ability to run code (RPC? Virtualization? Really, really good emulator?) on the target system, but then again, that's a limitation with any cross-compiling scenario. I don't understand this. If you're talking about version blocks, obviously all the current D compile time features are incompatible with the macro system. They're also redundant cause you can (and should) simply write instead: macro (version) { if (version == Version.Linux) { ...} } Also, the macro dll is compiled for some platform Z and will only be loadable by a compiler that also runs on platform Z. I don't think that macros need to be cross-compiled for our (X,Y) scenario, they need to evaluate a TargetPlatform parameter at their run-time which the cross-compiler will provide (much like current D have predefined version identifiers defined by the compiler)
Re: Why Ruby?
Sat, 18 Dec 2010 16:01:37 -0800, Walter Bright wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab In case you didn't see, two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort in the sorting example) - symbol visibility problems because of wrong scoping
try...catch slooowness?
Hello, I had not initially noticed that the 'in' operator (for AAs) returns a pointer to the looked up element. So that, to avoid double lookup in cases where lookups may fail, I naively used try...catch. In cases of very numerous lookups, my code suddenly became blitz fast. So that I wondered about exception handling efficiency. Below a test case (on my computer, both loops run in about the same average time): void main () { byte[uint] table = [3:1, 33:1, 333:1]; byte b; byte* p; Time t0; uint N1 = 246, N2 = 999; // try...catch t0 = time(); foreach (n ; 0..N1) { try b = table[n]; catch (RangeError e) {} } writefln(try...catch version time: %sms, time() - t0); // pointer t0 = time(); foreach (n ; 0..N2) { p = (n in table); if (p) b = table[n]; } writefln(pointer version time: %sms, time() - t0); writefln(pointer version is about %s times faster,N2/N1); } == try...catch version time: 387ms pointer version time: 388ms pointer version is about 40650 times faster Note that both versions perform a single lookup trial; the difference thus only lies in pointer deref vs try...catch handling, i guess. What do you think? Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: Why Ruby?
Sun, 19 Dec 2010 01:24:43 +, JRM wrote: On Sat, 18 Dec 2010 16:01:37 -0800, Walter Bright wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab ? I agree that those aren't really much better. This entire discussion seems a little odd to me. People are trying to find a way to more easily write lambda's, focusing in particular on single expression lambda's. Have you got any idea what a 'lambda' actually is? It originates from the lambda calculus. In lambda calculus the lambda abstraction is something that takes a single argument and returns an *expression*. You can argue that this is less general than D's delegates, but the fact is that many such functions such as sort, filter, map, reduce, ... return an expression. Of course the explicit return generates additional syntactic bloat. In order to support lazy, D already allows an expression to be implicitly converted to a delegate returning either void or the type of the expression. This covers the case of lambda's taking no arguments, and happens to be shorter than any of the proposed syntaxes. Sorry, don't remember how this works in D if you actually call the function with a delegate that isn't taking any arguments, but if the lazy generates another thunk, this doesn't work consistently. I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. So in your opinion D's function literals should only be improved if you can somehow outwit existing languages, otherwise it just sounds like a stupid idea?
Re: Game development is worthless? WTF? (Was: Why Ruby?)
On 12/18/2010 10:03 PM, Nick Sabalausky wrote: Caligoiteronve...@gmail.com wrote in message news:mailman.5.1292651710.4588.digitalmar...@puremagic.com... IMO there is no honor in game development as it contributes nothing to society. I've rarely played any, I gotta jump on this as being a giant load of pretentous bullshit. First of all, there's the patently obvious how in the world would you know? considering the I've rarely played any. But more importantly, games make life suck less - I can't even imagine any more significant contribution to society than that. Even all of the endevors generally considered to be the biggest contributions to society are *only* significant contributions *because* that's exactly what they do: they make life suck less, and are therefore well-regarded. I hear you! People please legalize drugs. They make my life suck so much less. Seriously, what up with all those presumptuous assholes out there (mostly baby boomer dinos and their even more anachronistic parents, interestingly enough) who have barely ever touched a videogame and yet figure they actually have reason to believe such absurd pretentous crap? Fuck, they all remind me of that pompous Roger Ebert douchebag. (Speaking of ways to benefit society, when's he finally gonna keel over? Isn't it about time by now? And speaking of contributions to society what the fuck's he ever done? Collect a salary just to spout off opinions? Fucking useless wanker.) Countless hours of my life have gone to waste while I've been killing zergs and protos. Still, my life sucks so much less because of that gorgeous feeling the unpunished killing gives me. The only thing I keep regretting (at the rare moments when I am not high) is I could have created something useful instead. Maybe, yet another programming language, in which more cool games could have been written.
Re: try...catch slooowness?
spir: try...catch version time: 387ms pointer version time: 388ms pointer version is about 40650 times faster Those numbers look wrong :-) What do you think? Compared to Oracle Java VM the DMD exceptions are very slow. Performance tuning of DMD is left for later, when the main features are all present. Bye, bearophile
Re: try...catch slooowness?
On 2010-12-19 07:33:29 -0500, spir denis.s...@gmail.com said: // pointer t0 = time(); foreach (n ; 0..N2) { p = (n in table); if (p) b = table[n]; } But why the double lookup? Just dereference the pointer: foreach (n ; 0..N2) { p = (n in table); if (p) b = *p; } -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Game development is worthless? WTF? (Was: Why Ruby?)
On Sun, 19 Dec 2010 05:19:50 -0500 bearophile bearophileh...@lycos.com wrote: Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) rather The Battle for Wesnoth ;-) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: New syntax for string mixins
Don nos...@nospam.com wrote: I don't think it's quite the same. In a makefile, every executable is listed, and so you can have some degree of control over it. But in this scenario, the compiler is making calls to arbitrary shared libraries with arbitrary parameters. It means the compiler cannot be trusted *at all*. You are right only partially - it's unsafe for browser language where code is taken from untrusted source. But this feature gives so much power to the macro sysrem - that I think is worth considering it. IMO, usually compiled code is run just after compilation (with the same prermissions as compiler) - so compiled code can make dangerous things and can't be trusted at all, but no one is worry about that. Yes compiler can't be *trusted* with this features, but if one knows what he is doing, why to prevent him - add option --enable-ctfe-DANGEROUS-features to allow potentially dangerous features then it wouldn't be so unexpected. Are those features hard to add to the current implementation?
Re: try...catch slooowness?
On Sun, 19 Dec 2010 07:47:11 -0500 Michel Fortin michel.for...@michelf.com wrote: On 2010-12-19 07:33:29 -0500, spir denis.s...@gmail.com said: // pointer t0 = time(); foreach (n ; 0..N2) { p = (n in table); if (p) b = table[n]; } But why the double lookup? Just dereference the pointer: foreach (n ; 0..N2) { p = (n in table); if (p) b = *p; } Oops, sorry, code copy error. But this does not change the test result times (because nearly no key exists in the table). denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: emscripten
Adam Ruppe: Which brings me to emscripten... it most certainly does not work well! The Python example took a couple *minutes* to load for me, and actually running some python code took seconds each time. On a more modern browser it works well enough (Firefox 4). Do you realize that the source code of CPython is a LOT of code, we are talking about a JavaScript source file of 2.6 MB, after compression! So just seeing it compile and be able to run it and run some Python scripts is a marvel for me :-) So I think emscripten is a very nice toy. I have not yet tried to use LDC emscripten to convert some D1 code to JS. Regarding the JavaScript language, they are going to fix some of its biggest mistakes (but not semicolons yet, hopefully later), so JS is gaining speed, fixing its mistakes, and gaining power (canvas, WebGL, audio, video, other widgets, frameworks, etc): http://www.yuiblog.com/blog/2010/12/14/strict-mode-is-coming-to-town/ An interesting part from that blog post, that reminds us that D2 has sadly failed to fix this problem (and the octal!x syntax is not a significant improvement of the situation): In C, an extremely unfortunate representation of octalness was selected: Leading zero. So in C, 0100 means 64, not 100, and 08 is an error, not 8. Even more unfortunately, this anachronism has been copied into nearly all modern languages, including JavaScript, where it is only used to create errors. It has no other purpose. So in strict mode, octal forms are no longer allowed. Bye, bearophile
Re: try...catch slooowness?
On Sun, 19 Dec 2010 07:46:09 -0500 bearophile bearophileh...@lycos.com wrote: spir: try...catch version time: 387ms pointer version time: 388ms pointer version is about 40650 times faster Those numbers look wrong :-) I thought so. But in the real app a loop that lasted ~ 10s suddenly became instantaneous (human perception ;-) Try it. Sorry, but I'm not inventing the numbers. What do you think? Compared to Oracle Java VM the DMD exceptions are very slow. Performance tuning of DMD is left for later, when the main features are all present. And what if the numbers are correct? Exception handling is explicitely recommanded in some docs --as opposed to C-like manual hacks. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: try...catch slooowness?
spir wrote: Hello, I had not initially noticed that the 'in' operator (for AAs) returns a pointer to the looked up element. So that, to avoid double lookup in cases where lookups may fail, I naively used try...catch. In cases of very numerous lookups, my code suddenly became blitz fast. So that I wondered about exception handling efficiency. Below a test case (on my computer, both loops run in about the same average time): Catching exceptions is known to be a bit costly. Generally, in C family languages with exceptions (such as D), it is considered bad practice to use exceptions for regular control flow. The cost is therefore acceptable because it is not suffered on the normal, happy code path. That the performance cost is so huge is likely not only the inherent overhead of exceptions, but probably also some extra cache misses or something like that.[needs analysis]
Re: executable size
jovo Wrote: Hi, Today I compiled my old two module console program with d-2.50. It uses only std.c.time, std.c.stdio, std.random and templates. Compiled with -O -release, on windows. Executable size (d-2.50): 4.184 kb. Trayed with d-1.30: 84 kb. Is it expected? This is something you shouldn't worry too much about. Hard drives and system memory are getting bigger. 4 megabytes isn't that much when you have soon 4 terabytes of space. A single PC rarely has one million executables. So, keep writing more code. That's what the space is for. - G.W.
Re: Why Ruby?
Stephan Soller stephan.sol...@helionweb.de wrote: I don't think that the syntax improvement of chaining is worth such an effort. It adds tons of complexity for only a very limited gain. I'm not sure if I could write such self-parsed code without thinking about that pipeline. I think I don't fully understand what you mean by syntax improvement for chaining. This my code is almost possible to run but needs some time and work (to get round CTFE limitations, enhance parser). But syntax parser behind it is rather primitive, if to use external tools one can make much better syntax parsers with much less efford.
Re: try...catch slooowness?
On 2010-12-19 08:17:07 -0500, spir denis.s...@gmail.com said: On Sun, 19 Dec 2010 07:46:09 -0500 bearophile bearophileh...@lycos.com wrote: spir: try...catch version time: 387ms pointer version time: 388ms pointer version is about 40650 times faster Those numbers look wrong :-) I thought so. But in the real app a loop that lasted ~ 10s suddenly became instantaneous (human perception ;-) Try it. Sorry, but I'm not inventing the numbers. What looks wrong is that the output seem to say that 388ms was 40650 times faster than 387ms. Obviously, by looking at the code one can understand that you adjusted the number of iteration to get the same time for both versions, and from that number of iteration you can claim the pointer version is about X times faster. But the output alone is misleading. Add the iteration count to the output and it'll be easier to read. Exceptions are slow, that's a fact of life. The idea is that an exception should be exceptional, so the case to optimize for is the case where you don't have any exception: a try...catch that doesn't throw. Other ways to implement exceptions exists which are faster at throwing (setjmp for instance), but they're also slower at entering and exiting a try..catch block when no exception occur. What do you think? Compared to Oracle Java VM the DMD exceptions are very slow. Performance tuning of DMD is left for later, when the main features are all present. And what if the numbers are correct? Exception handling is explicitely reco mmanded in some docs --as opposed to C-like manual hacks. Exceptions are recommended to avoid cluttering your normal code flow with error handling code. Clearly, in the code above exceptions are part of the normal code flow. That's not what exception are made for. That said, I'd encourage you to profile this test case to see where the time is being spent. You might find one or two places that can be improved in the part of the runtime dedicated to exceptions. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: is it possible to learn D(2)?
Andrei Alexandrescu Wrote: On 12/18/10 3:44 PM, Jeff Nowakowski wrote: On 12/18/2010 03:16 PM, Don wrote: Jeff Nowakowski wrote: D2 has *never* been officially released (like D1 was), though its release was supposed to coincide with the release of Andrei's book. Where did you get that idea? I've never heard it before. (Genuine question, I'd like to know where that impression came from). Which idea are you questioning? That D2 hasn't been released, or that the two were supposed to come out together? The answer to both would be the newsgroup. There was plenty of talk about them coming out together, and then time went by, and Andrei's book was relatively quietly released (unless I missed some big announcement; my memory was of posts trickling in of people who had pre-ordered), and no mention was made of D2 being released any more along with the book. I can dig up posts if you like, but I'd rather not unless any of this is in dispute. I don't think it's worth investigating this, but at any rate my thinking has been that finalizing TDPL would finalize the specification of D2. Of course, ideally the compiler would follow the specification as closely as possible, but with the number of extant issues it has always been pretty clear that conformance will be trailing. The book hasn't been released quietly at all; I've sent numerous updates to this group (just search for TDPL in the title) and my website has made the event as prominent as it could. As it was clearly highly anticipated in this group, laying it any thicker would have been inappropriate. Walter and Andrei haven't been very honest in their presentations on the state of the language. I think the initial estimate of how long things would take was wildly optimistic. I am certain that there's been no intention to be dishonest, at any stage. Andrei gives other people a lot of shit over only showing the positive in their presentations. Both Andrei and Walter have misrepresented the open source compiler issues on their slides (and Walter had no excuse after Andrei was called for it on the newsgroup). I saw Andrei's Google presentation and he talked a lot about D2 features and gave away a lot of books, but never once said that D2 was still being implemented and that serious bugs remained. A fair point. Well I didn't give away a lot of books, I gave three, and specifically for the three most embarrassing questions. (My budget of giveaway books is fairly limited.) Does this mean that Facebook is not paying you that well, after all? I could donate like $82 to you to give away three more books. No need to mention my name, after all I'm just helping the poor.
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Seeing the enemy being literally eaten by hundreds of upgraded zerglings has no comparison. :-)
Re: Purity
On Sat, 18 Dec 2010 01:27:40 -0500, Don nos...@nospam.com wrote: Steven Schveighoffer wrote: On Fri, 17 Dec 2010 09:39:19 -0500, Don nos...@nospam.com wrote: A function which has immutably pure parameters can undergo *some* optimisation, even if the return value is a mutable pointer. For example, if the parameters are identical for both calls, you can do a deepdup of the first return value instead of calling the function again. Yes, I agree with this. However, I still believe statement 1 is still correct, because you really have just introduced a third class of pure functions that I was not aware of :) So we have: weak-pure functions : functions which can accept and return any type of values, but can only call pure functions and cannot access global state. middle-pure ? functions : weak-pure functions which accept only immutable or implicitly convertable to immutable values, but returns a mutable reference. strong-pure funtions : pure functions which accept and return only immutable or implicitly convertible to immutable values. There actually could be another class, const-pure functions: pure functions which accept and return only const or implicitly convertible to const values. The problem with these ones, is there could be aliasing between the input and the output. Do they have any interesting properties? They can act like strong-pure functions when all the arguments being passed in are IOICTI (immutable or implicitly convertable to immutable). Another interesting one is a function with all-const parameters, that returns a mutable reference that has only mutable or immutable members. (ie, nothing const). Like the one you've called middle-pure, this returns a unique result, because you're guaranteed there is no aliasing. Yes. I suspect the compiler will need to classify things as strong or weak pure, and store various attributes on weak-pure functions to see what optimizations can be had. The compiler does that already. OK, good. -Steve
Re: Why Ruby?
On 12/19/10 5:01 AM, Simen kjaeraas wrote: Walter Bright newshou...@digitalmars.com wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab ? No. But often, you want to call a function in a lambda, in which case the string version croaks. I'm not sure about the often part. For me, string lambdas do often suffice. When it doesn't, I use a lambda. D's syntax for lambdas is not syntactically heavy at all: (a, b) { return a + b; } The proposed alternative gravitates around (a, b) - { a + b } So this discussion concerns a niche between short lambdas that can be expressed as strings and lambdas for which the actual word return is too much to type. In fact we're looking at the difference between return + ; and - . Four characters. If the new syntax would be executed to perfection, to what extent would that improve your use of D? To what extent would it make the language more powerful? To what extent does it allow to do things you otherwise wouldn't be able to? Equally importantly, where is this four-characters saver on the radar compared to fixing const's issues, discussing tail const, completing and then improving 64-bit support, fixing important bugs, or even adding the lambda lowering that was discussed earlier in this thread to be promptly forgotten? Also, it is not always possible to pass the lambda by template alias parameter, in which case the string version is right out the window. unaryFunc!a + b As for functions taking a delegate, the {=@+@;} syntax will not work with overloading or template functions (nor will the other syntaxen that elides types). It could also be that functions taking delegates are or should be rare, and thus not worth optimizing for. I have no idea what {=@+@;} does - it looks like a wrong paste from an early dialect of Perl to me. I have difficulty picturing someone who finds a+b or q{a+b} ugly but some other syntaxes discussed here palatable. Andrei
Re: Why Ruby?
On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. Please use the notion of syntactic hygiene correctly. Andrei
Re: Why Ruby?
On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); That does work. What doesn't work is calling nonmember functions looked up in the context of the caller. Andrei
Re: Why Ruby?
On 12/19/10 6:26 AM, retard wrote: Sat, 18 Dec 2010 16:01:37 -0800, Walter Bright wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab In case you didn't see, two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort in the sorting example) This can be solved by using a canonicalizer before passing to unaryFun. I considered doing that, but delayed implementing it to when this would actually become a problem. - symbol visibility problems because of wrong scoping Scoping is not wrong, it's just different :o). I agree that that can be an issue - in which case you take the enormous hit of writing (a, b) { stmts }, of which the proposals passionately discussed within save a grand total of around four characters. Again: to what extent does this help on becoming able to do what you want to do in D, and where is implementing this ranked in comparison to the other work items? Andrei
Optimizing delegates
I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. - When using string mixins, as mentioned by several others, if I invoke a function, that function is evaluated in the scope of foobar2, not in the original scope. That limits a lot what I can pass a string. - That means that if I want my users to use either strings or delegates I have to take that into account, complicating a lot the function signature and the implementation. - That also means I can't always have hyper-high performance because if I need to do something but I can't do it with a string I have to rely on delegates, which won't be optimized. - Understanding foobar2 is harder than understanding foobar. First, it has two statements. :-P. Then I have to concatenate the strings in my head to form the resulting function. And that one is a simple one, so for a complex one it must be even harder to understand. From all of these points I can see string mixins are not a very good idea to be used as callback functions, the main reasons being: it doesn't always work, it's harder to read and to write and it makes the object file bigger. So my suggestion is: optimize delegates! Take some time to optimize them to the maximum and then you won't need string mixins. If foobar here can be optimized like foobar2, that's it! Why would anyone want to write a function like foobar2 if the resulting code will be the same? So here's an idea, it just ocurred to me while writing this post. In the code above, the compiler sees this: writefln(%d, foobar((int x) { return 2*x; })); foobar is this: int foobar(int delegate(int) f) { return f(1); } It sees foobar takes a delegate, so what it does it creates a function foobar_1 (or some name not already used) that results from rewriting foobar with the delegate inlined: int foobar_1(int delegate(int) f) { return 2*1; } So now we have: writefln(%d, foobar_1((int x) { return 2*x; })); It then optimizes that line and ends up with this: writefln(%d, 2); (and I checked if dmd inlines that call, because it passes a delegate it doesn't use, and yes, it is being inlined). Then the compiler can discard foobar_1 because it doesn't use it anymore. No object file bloat, full speed. What if the delegate is more complex? Let's try: writefln(%d, foobar((int x) { int a = 10; return a*x; })); int foobar_1(int delegate(int) f) { int delegateResult; { int a = 10; delegateResult = a*1; // 1 was x } return delegateResult; } More complex: int bar(int y) { return y * 3; } writefln(%d, foobar((int x) { return bar(x); })); For this case... I don't know. Maybe it could define bar inside of foobar_1 again, or maybe rewrite foobar_1 to accept another delegate and pass bar to it, and then reapply this algorithm. Anyhow... maybe what I say doesn't make sense at all, it's the wrong way to optimize code or whatever. My point is: if the compiler were smarter I wouldn't need string mixins to get my code optimized. If you are going to define fancy functions like map, sort, and other functions that basically receive callback functions, optimize those callback to the maximum, don't make the users optimize those callbacks by using string mixins. It's very frustrating for the user, when she has to sit down and write a high-performance function, to think Ok, how can I write this code so the compiler already sees it as being very easy to optimize?. With D it's not about thinking about the data-structures to use and the algorithms to use anymore, it's about thinking about writing code that looks easy to optimize for the compiler. :-(
Re: Why Ruby?
On 2010-12-18 21:48, Simen kjaeraas wrote: bearophile bearophileh...@lycos.com wrote: Jacob Carlborg: 1 D: foo(writeln(3)); // lazy argument 1 Scala: foo(_ * _) 2 C#: foo(x = x * x); 3 Scala: foo((x) = x * x) 4 Python: foo(lambda x: x * x) 5 Ruby: foo { |bar| x * x } 5 Ruby: foo do |x| x * x end 6 D: foo((int x) { return x * x; }); 7 C++1x: foo([](int x){ return x * x; }); 7 Apple's (Objective)-C(++) block extension: foo(^(int x){ return x * x; }); 8 JavaScript: foo(function(x){ return x * x }) 9 PHP: foo(function ($x) use($fooBar) { return $x * $x; }); // use is used for explicitly telling what variables should be available when the scope is gone. (In D there are template lambdas too). This topic was discussed some in past. I like a syntax similar to: foo({x,y = x * y}) foo({int x, int y = x * y}) I really like this. The curly braces clearly show it to be a new scope, and the syntax is concise and understandable. I don't like it, it's not enough improvement. Compared to this suggestion I think the current syntax is good enough. -- /Jacob Carlborg
Re: Why Ruby?
On 2010-12-18 22:50, retard wrote: Sat, 18 Dec 2010 19:09:24 +0100, Jacob Carlborg wrote: As Nick writes here the Scala/C#-style syntax is one suggestion. There are also several other syntaxes available, one just have to look at other languages to get ideas. Here's a list of the syntax used by a couple of different language, some languages are list more than once because they support more than one syntax. I've listed the languages in order from, what I think, the least verbose to the most verbose lambda/delegate syntax (the number in front of the languages is the level of verbose, if two languages are at the same level I think they are equally verbose). 1 D: foo(writeln(3)); // lazy argument That's not really equivalent to lambdas. It would be unfair to not mention Scala which also supports lazy arguments. It depends on how you see it. It passes in a piece of code that can be executed in foo. And when you see if like this I think the Scala syntax I mention below is the basically the same. (BTW, I mentioned it was lazy argument and not a delegate). 1 Scala: foo(_ * _) This isn't the same. _ * _ is equivalent to (a, b) = a * b I know that, but as far as I know I cannot do the same with D's lazy arguments. 1 Scala: foo(x = x * x) 2 C#: foo(x = x * x); 3 Scala: foo((x) = x * x) foo(x = x * x) also works in this case 4 Python: foo(lambda x: x * x) 5 Ruby: foo { |bar| x * x } Maybe you meant foo { |x| x * x } 5 Ruby: foo do |x| x * x end 6 D: foo((int x) { return x * x; }); 7 C++1x: foo([](int x){ return x * x; }); 7 Apple's (Objective)-C(++) block extension: foo(^(int x){ return x * x; }); 8 JavaScript: foo(function(x){ return x * x }) 9 PHP: foo(function ($x) use($fooBar) { return $x * $x; }); // use is used for explicitly telling what variables should be available when the scope is gone. Note that I have not listed any functional languages here because I've never used one. For example: Lambda calculus: λx.x*x Haskell: \x - x * x As you can see, most of the verbosity comes from the fact that lambdas in D and C++ contain statements, not a single expression. It's like if-then- else vs ternary ?: -- In languages like Scala these are the same built-in feature. Yeah. -- /Jacob Carlborg
Re: Why Ruby?
Imagine you don't have to write semicolons in D. If you have 1000 lines of code you save 1000 keystrokes and characters to read. If you have about 50 delegates in your code you save 200 characters. I don't think this is more important than the other problems you mention, but adding bits of characters here and there ends up saving a lot.
Re: Why Ruby?
On 2010-12-18 23:41, Walter Bright wrote: Jacob Carlborg wrote: foo(x, y = x * y); The problem with all these is what is the difference between: { x * y } { x * y; } == note the ; { return x * y; } I would say there is no difference. The delegeate would be inferred to have the same type as the function requires. Take this for example, foo is declared like this: void foo (int delegate (int x, int y) dg); And called like this: foo(x, y = x * y); Then the delegate would be inferred to be: int delegate (int, int) If you add a semicolon or a return in the lambda body it would be inferred to the same type. The C++ lambda group had the same discussions. It may not seem like much when the code is trivial, but when it gets more complex, having 2 or 3 different syntaxes for function bodies seems like a confusing disaster in the making. The point is to only use the syntax when the code is trivial, like in the above example. -- /Jacob Carlborg
Re: Why Ruby?
On 2010-12-19 03:13, Walter Bright wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. Apparently it has several flaws as other have mentioned in this thread. -- /Jacob Carlborg
Re: Why Ruby?
On 12/19/10 9:49 AM, Ary Borenszweig wrote: Imagine you don't have to write semicolons in D. If you have 1000 lines of code you save 1000 keystrokes and characters to read. If you have about 50 delegates in your code you save 200 characters. The way you measure to assess whether this is material is in proportion to the rest of the code. Semicolons are quite frequent, but 200 characters in 1000 lines may be as infrequent as 0.2%. I don't think this is more important than the other problems you mention, but adding bits of characters here and there ends up saving a lot. I agree in principle, but not in this case. Andrei
Re: Why Ruby?
On 2010-12-19 01:01, Nick Sabalausky wrote: Walter Brightnewshou...@digitalmars.com wrote in message news:iejejo$pf...@digitalmars.com... Nick Sabalausky wrote: Any problem with the other Scala/C#-style one?: (x, y) = x * y // Lowered to: (x, y) { return x * y; } (Maybe that was rejected before due the the weird float operators that are now being ditched?) The problem with the (x,y) parameter lists, where x and y are the parameters, is that it is ambiguous with the existing syntax of (x,y) where x and y are types and the parameters are omitted. For example: void foo(int); But we already have: (x, y) { return x * y; } So either there aren't any problems with it after all, or D's existing delegate syntax is already broken. To be clear, with what I'm trying to suggest, the *only* thing that would be different from the current delegate literal syntax is that part *after* the parameter list. Ie: PARAM_LIST_HERE { return x * y; } // -- PARAM_LIST_HERE = x * y Or if there's a problem with =, then -, or --, or ::, or :, or whatever. I'm not suggesting the param list be different in any way fromhow t is now. (Although proposals from other people might differ.) ^^ Exactly. I would also like to have type inference for the parameter list, do we have that already in D2? -- /Jacob Carlborg
Re: Why Ruby?
On 2010-12-19 01:01, Walter Bright wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab ? No, that syntax is not better. -- /Jacob Carlborg
Re: is it possible to learn D(2)?
On 12/19/10, lurker l...@lurk.net wrote: Does this mean that Facebook is not paying you that well, after all? I could donate like $82 to you to give away three more books. No need to mention my name, after all I'm just helping the poor. I'm pretty sure it means he got a couple of free books from the publisher to give away for free. ;)
Re: Why Ruby?
On 2010-12-19 16:14, Andrei Alexandrescu wrote: On 12/19/10 5:01 AM, Simen kjaeraas wrote: Walter Bright newshou...@digitalmars.com wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab ? No. But often, you want to call a function in a lambda, in which case the string version croaks. I'm not sure about the often part. For me, string lambdas do often suffice. When it doesn't, I use a lambda. D's syntax for lambdas is not syntactically heavy at all: (a, b) { return a + b; } The proposed alternative gravitates around (a, b) - { a + b } I never proposed that exact syntax, I don't think anyone else did either. I think just one person mentioned -. This is the syntax I've proposed: foo(3 * 4); // lazy argument/delegate foo(a = a * 3); foo(a, b = a * b); // or if not possible: foo((a, b) = a * b); So this discussion concerns a niche between short lambdas that can be expressed as strings and lambdas for which the actual word return is too much to type. In fact we're looking at the difference between return + ; and - . Four characters. No, you also added the {} characters. If the new syntax would be executed to perfection, to what extent would that improve your use of D? To what extent would it make the language more powerful? To what extent does it allow to do things you otherwise wouldn't be able to? Nothing, but there are a lot of things you can say the same about. I've also got the impression that you are pushing for a more functional approach of coding and for that a short, good and working lambda syntax is necessary. Equally importantly, where is this four-characters saver on the radar compared to fixing const's issues, discussing tail const, completing and then improving 64-bit support, fixing important bugs, or even adding the lambda lowering that was discussed earlier in this thread to be promptly forgotten? If this isn't a very quick implementation this would low on the priority list. I would like to have the lambda lowering as well :) Also, it is not always possible to pass the lambda by template alias parameter, in which case the string version is right out the window. unaryFunc!a + b As for functions taking a delegate, the {=@+@;} syntax will not work with overloading or template functions (nor will the other syntaxen that elides types). It could also be that functions taking delegates are or should be rare, and thus not worth optimizing for. I have no idea what {=@+@;} does - it looks like a wrong paste from an early dialect of Perl to me. I have difficulty picturing someone who finds a+b or q{a+b} ugly but some other syntaxes discussed here palatable. Andrei That syntax is just ugly. -- /Jacob Carlborg
Re: Why Ruby?
On 2010-12-19 16:23, Andrei Alexandrescu wrote: On 12/19/10 6:26 AM, retard wrote: Sat, 18 Dec 2010 16:01:37 -0800, Walter Bright wrote: Simen kjaeraas wrote: The problem of D's lambda syntax is it is optimized for longer functions. Usually, the delegates I write are one line long. I cannot see that this syntax collides with anything at the moment, but feel free to enlighten me: { = 4; } { a = 2*a; } { a, b = ab; } { = @ + @; } // turns into { a, b = a + b; } If size and simplicity of typing are critical, are those really better than: ab In case you didn't see, two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort in the sorting example) This can be solved by using a canonicalizer before passing to unaryFun. I considered doing that, but delayed implementing it to when this would actually become a problem. I can clearly see that you haven't used an Objective-C/D bridge. The reason (or at least one of the reasons) for which Michel Fortin (as well as I) gave up the Objective-C/D bridge and started to modify DMD is template bloat. I'm not saying that using template strings as lambdas is going to bloat your executable/library as much as the bridge does but I always think twice before adding a template to my code. - symbol visibility problems because of wrong scoping Scoping is not wrong, it's just different :o). I agree that that can be an issue - in which case you take the enormous hit of writing (a, b) { stmts }, of which the proposals passionately discussed within save a grand total of around four characters. I don't know why but you added the {} characters. Again: to what extent does this help on becoming able to do what you want to do in D, and where is implementing this ranked in comparison to the other work items? Andrei -- /Jacob Carlborg
Re: Optimizing delegates
On 2010-12-19 16:32, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. - When using string mixins, as mentioned by several others, if I invoke a function, that function is evaluated in the scope of foobar2, not in the original scope. That limits a lot what I can pass a string. - That means that if I want my users to use either strings or delegates I have to take that into account, complicating a lot the function signature and the implementation. - That also means I can't always have hyper-high performance because if I need to do something but I can't do it with a string I have to rely on delegates, which won't be optimized. - Understanding foobar2 is harder than understanding foobar. First, it has two statements. :-P. Then I have to concatenate the strings in my head to form the resulting function. And that one is a simple one, so for a complex one it must be even harder to understand. From all of these points I can see string mixins are not a very good idea to be used as callback functions, the main reasons being: it doesn't always work, it's harder to read and to write and it makes the object file bigger. So my suggestion is: optimize delegates! Take some time to optimize them to the maximum and then you won't need string mixins. If foobar here can be optimized like foobar2, that's it! Why would anyone want to write a function like foobar2 if the resulting code will be the same? So here's an idea, it just ocurred to me while writing this post. In the code above, the compiler sees this: writefln(%d, foobar((int x) { return 2*x; })); foobar is this: int foobar(int delegate(int) f) { return f(1); } It sees foobar takes a delegate, so what it does it creates a function foobar_1 (or some name not already used) that results from rewriting foobar with the delegate inlined: int foobar_1(int delegate(int) f) { return 2*1; } So now we have: writefln(%d, foobar_1((int x) { return 2*x; })); It then optimizes that line and ends up with this: writefln(%d, 2); (and I checked if dmd inlines that call, because it passes a delegate it doesn't use, and yes, it is being inlined). Then the compiler can discard foobar_1 because it doesn't use it anymore. No object file bloat, full speed. What if the delegate is more complex? Let's try: writefln(%d, foobar((int x) { int a = 10; return a*x; })); int foobar_1(int delegate(int) f) { int delegateResult; { int a = 10; delegateResult = a*1; // 1 was x } return delegateResult; } More complex: int bar(int y) { return y * 3; } writefln(%d, foobar((int x) { return bar(x); })); For this case... I don't know. Maybe it could define bar inside of foobar_1 again, or maybe rewrite foobar_1 to accept another delegate and pass bar to it, and then reapply this algorithm. Anyhow... maybe what I say doesn't make sense at all, it's the wrong way to optimize code or whatever. My point is: if the compiler were smarter I wouldn't need string mixins to get my code optimized. If you are going to define fancy functions like map, sort, and other functions that basically receive callback functions, optimize those callback to the maximum, don't make the users optimize those callbacks by using string mixins. It's very frustrating for the user, when she has to sit down and write a high-performance function, to think Ok, how can I write this code so the compiler already sees it as being very easy to optimize?. With D it's not about thinking about the data-structures to use and the algorithms to use anymore, it's about thinking about writing code that looks easy to optimize for the compiler. :-( I completely agree with this post. -- /Jacob Carlborg
Re: is it possible to learn D(2)?
On 12/19/10 9:57 AM, Andrej Mitrovic wrote: On 12/19/10, lurkerl...@lurk.net wrote: Does this mean that Facebook is not paying you that well, after all? I could donate like $82 to you to give away three more books. No need to mention my name, after all I'm just helping the poor. I'm pretty sure it means he got a couple of free books from the publisher to give away for free. ;) The main issue is perceived value. Books are not T-shirts as significant time would have to be spent on reading them. Say I had 40 people in the audience and 40 books. Then it would have been like passing around marketing samples of no perceived value. Andrei
Re: Optimizing delegates
On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei
Re: Game development is worthless? WTF? (Was: Why Ruby?)
bearophile Wrote: Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) He does however write games sometimes: http://www.classicempire.com/
Re: Optimizing delegates
On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize?
Re: Game development is worthless? WTF? (Was: Why Ruby?)
You are absolutely right; life sucks for many people, and that's why some of them choose to play video games. It gives them a chance to escape reality, and game companies exploit this to make money. Game companies use all kinds of psychology in their games to keep you playing as long as possible. That is why to me there is no honor in game development. Also, I never said it's worthless; they make tons of money, and that's almost always at the expense of people like you. If it helps any, I'm not one of those baby boomers. I'm actually in my early twenties. So if you are going to insult me at least do it properly. You sound way too angry and unhappy. Instead of playing video games, you should definitely pick up Ruby if you haven't already. I hear it's designed to make programmers happy. On Sat, Dec 18, 2010 at 2:03 PM, Nick Sabalausky a...@a.a wrote: Caligo iteronve...@gmail.com wrote in message news:mailman.5.1292651710.4588.digitalmar...@puremagic.com... IMO there is no honor in game development as it contributes nothing to society. I've rarely played any, I gotta jump on this as being a giant load of pretentous bullshit. First of all, there's the patently obvious how in the world would you know? considering the I've rarely played any. But more importantly, games make life suck less - I can't even imagine any more significant contribution to society than that. Even all of the endevors generally considered to be the biggest contributions to society are *only* significant contributions *because* that's exactly what they do: they make life suck less, and are therefore well-regarded. Seriously, what up with all those presumptuous assholes out there (mostly baby boomer dinos and their even more anachronistic parents, interestingly enough) who have barely ever touched a videogame and yet figure they actually have reason to believe such absurd pretentous crap? Fuck, they all remind me of that pompous Roger Ebert douchebag. (Speaking of ways to benefit society, when's he finally gonna keel over? Isn't it about time by now? And speaking of contributions to society what the fuck's he ever done? Collect a salary just to spout off opinions? Fucking useless wanker.)
Re: Optimizing delegates
On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei
Offense programming
This author shows a bit of exasperation caused by the current crop of programming languages. No popular language around today seems fit for high integrity systems. I think with some changes, improvements and restrictions D may become fit for this small but important niche: http://blog.kickin-the-darkness.com/2010/12/defensive-programming-fortran-ada-c.html Bye, bearophile
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Patrick Down wrote: bearophile Wrote: Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) He does however write games sometimes: http://www.classicempire.com/ I've never played WoW, but I have played Empire, and let me tell you, it wastes a lot more than 6 hours a day! I've been hesitant to play another round after last time, when I spent almost a full week just conquering the world. Got way behind on my work. I personally like the DOS version best. It reminds me so much of some of my early games. Same beautiful graphics and easy controls.
Re: Optimizing delegates
On 12/19/2010 06:35 PM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) int foobar3(alias f)() { return f(1); } alias template parameters accept everything that variadic template parameters do (including delegate literals) with the unfortunate exception of basic types :-O.
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Caligo: Game companies use all kinds of psychology in their games to keep you playing as long as possible. That is why to me there is no honor in game development. Also, I never said it's worthless; they make tons of money, and that's almost always at the expense of people like you. Many games are like drugs. That's very bad. But people need to play too, and there are instructive games too, for example games that develop your intuition about how dynamic systems work (SimCity and its followers), there are some smart games too. This is a game, but it's not so terrible for the mind of people, it's not a bad drug: http://armorgames.com/play/2205/light-bot Bye, bearophile
Re: Optimizing delegates
On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei foo.d --- import std.stdio; int foobar3(alias f)() { return f(1); } void main() { writefln(%d, foobar3!((x) { return 9876*x; })()); } aster...@deep-water:~/dmd2/linux/bin$ ./dmd foo.d -O -inline aster...@deep-water:~/dmd2/linux/bin$ ./obj2asm foo.o | vi - (line 530) _Dmain: pushEBP mov EBP,ESP mov EAX,offset FLAT:_d3std5stdio6stdouts3std5stdio4f...@sym32 pushdword ptr _t...@sym32[0eh] pushdword ptr _t...@sym32[010h] push02694h call _d3std5stdio4file19__t8writeflntayatiz8writeflnmfaya...@pc32 xor EAX,EAX pop EBP ret nop nop No, it doesn't seem to get inlined. Luckily. Because if it did get inlined then I would improve DMD by giving an error on this line: int foobar(int delegate(int) f) { ... } foo.d(3): Error: Hey man, what are you doing? Don't you know that if you pass delegates that way they don't get inlined? You should write it this way: int foobar(alias f)(). That is, of course, if you want your code to be more performant.
Re: Optimizing delegates
On 12/19/2010 01:57 PM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei foo.d --- import std.stdio; int foobar3(alias f)() { return f(1); } void main() { writefln(%d, foobar3!((x) { return 9876*x; })()); } aster...@deep-water:~/dmd2/linux/bin$ ./dmd foo.d -O -inline aster...@deep-water:~/dmd2/linux/bin$ ./obj2asm foo.o | vi - (line 530) _Dmain: push EBP mov EBP,ESP mov EAX,offset FLAT:_d3std5stdio6stdouts3std5stdio4f...@sym32 push dword ptr _t...@sym32[0eh] push dword ptr _t...@sym32[010h] push 02694h call _d3std5stdio4file19__t8writeflntayatiz8writeflnmfaya...@pc32 xor EAX,EAX pop EBP ret nop nop No, it doesn't seem to get inlined. Luckily. Because if it did get inlined then I would improve DMD by giving an error on this line: int foobar(int delegate(int) f) { ... } foo.d(3): Error: Hey man, what are you doing? Don't you know that if you pass delegates that way they don't get inlined? You should write it this way: int foobar(alias f)(). That is, of course, if you want your code to be more performant. Oops, sorry, it does get inlined, my mistake. I will submit a patch to DMD right now with the above error.
Re: is it possible to learn D(2)?
On Sun, Dec 19, 2010 at 10:16 AM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 12/19/10 9:57 AM, Andrej Mitrovic wrote: On 12/19/10, lurkerl...@lurk.net wrote: Does this mean that Facebook is not paying you that well, after all? I could donate like $82 to you to give away three more books. No need to mention my name, after all I'm just helping the poor. I'm pretty sure it means he got a couple of free books from the publisher to give away for free. ;) The main issue is perceived value. Books are not T-shirts as significant time would have to be spent on reading them. Say I had 40 people in the audience and 40 books. Then it would have been like passing around marketing samples of no perceived value. Andrei That's almost like saying all documentations, books, and reference materials licensed under GNU FDL are worthless because you don't have to pay for them. There are actually people who think that about FOSS; eh, if it was worth anything they wouldn't let you download the source code for free. I actually think your book would have been worth more if you had released it under GNU FDL or a similar license.
Re: Optimizing delegates
On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template.
Re: emscripten
bearophile: On a more modern browser it works well enough (Firefox 4). This is a bit of a rant, but I hate how the web community always uses modern browser like this. I ran this site on Firefox 3.6.3. The most recent one it offers on getfirefox.com is 3.6.13 - I'm not very far behind! My about firefox box says Gecko from April 2010. That should be modern by any sane definition! (Now, my every day browser, Konqueror 3.5.7, is (c) 2005. So I can understand it not being a modern browser. But it works for me so I won't change it. Something I find hilarious though: it's CSS2 compliance was better than firefox up until about last year! I just wrote a site going wild with css for a web demo for the company, and it worked almost as well in my old Konq as it did in my newer Firefox. The kde folks did a really impressive job there.) Anyway, it just irks me that so many web evangelists say modern when they really mean bleeding edge. And in Google's case, it is even worse: when they say all modern browsers, they actually mean /our/ bleeding edge beta. It really annoys me. Back on topic: So I think emscripten is a very nice toy. I agree completely, it's a cool toy and pretty impressive that they got it to work as well as they did. I just don't think it is usable or really desirable for real work. Maybe it will improve, but it still has to compete with straight up javascript, which is already good enough for most places where you really need it. Regarding the JavaScript language, they are going to fix some of its biggest mistakes (but not semicolons yet, hopefully later), Interesting. Some comments from the article, then back to you to comment on octal! at the end: Strict mode requires that all variable binding be done statically. I wonder how that will change the javascript this keyword. I originally found it confusing, but now that I know its rules it isn't so bad and is sometimes extra useful. You should explicitly declare all of your variables. Should?? If this is actually a strict mode, shouldn't it be must? Maybe the author is just being sloppy, but this wording makes me think it moved from implicit global to implicit local. Definitely better, but still requiring var in all cases is better yet. Noisy Failure Something important about failure is it isn't just the language. The environment needs to tell you too. Browsers often either hide errors or annoy you so much about them you want them hidden. Some support an onerror event so you can hook it yourself, but not all browsers do. It would be nice if the browser behavior on error in strict mode was improved too. ...or better yet, give us a compiler ahead of time! JSLint is OK I guess though, but I rarely use it. There are still problems in JavaScript that strict mode does not address. Yes, and those things still suck. But if you use js sparingly, you don't have to deal with them too much. :) Back to bearophile: (and the octal!x syntax is not a significant improvement of the situation): Sure it is! The problem is that the old syntax is still accepted instead of either breaking C or giving a compiler error. This is one place where Walter and I disagree, but to move to a new way, we eventually need to remove the old way.
Re: is it possible to learn D(2)?
On 12/19/10 11:00 AM, Caligo wrote: On Sun, Dec 19, 2010 at 10:16 AM, Andrei Alexandrescu seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org wrote: On 12/19/10 9:57 AM, Andrej Mitrovic wrote: On 12/19/10, lurkerl...@lurk.net mailto:l...@lurk.net wrote: Does this mean that Facebook is not paying you that well, after all? I could donate like $82 to you to give away three more books. No need to mention my name, after all I'm just helping the poor. I'm pretty sure it means he got a couple of free books from the publisher to give away for free. ;) The main issue is perceived value. Books are not T-shirts as significant time would have to be spent on reading them. Say I had 40 people in the audience and 40 books. Then it would have been like passing around marketing samples of no perceived value. Andrei That's almost like saying all documentations, books, and reference materials licensed under GNU FDL are worthless because you don't have to pay for them. There are actually people who think that about FOSS; eh, if it was worth anything they wouldn't let you download the source code for free. That's a completely different matter, but I won't insist as I'm sure you understand the extent to which you're forcing the comparison. I actually think your book would have been worth more if you had released it under GNU FDL or a similar license. I do a lot of work for free anyway so making money was not the first motivation. The thing is, however, that printed books still carry more authority than online ones, even though clearly there are many online books that compare favorably with the average printed book. Having a major publisher decide to take risks and invest money in producing at professional quality and marketing a book on a up-and-coming language is a clear signal that they believe in the success of the book and consequently that of the language. Andrei
Re: Optimizing delegates
On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei
Re: Optimizing delegates
On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ?
Re: Optimizing delegates
On 12/19/10 11:17 AM, Andrei Alexandrescu wrote: Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Let me add that good Lisp programmers understand that very well. Seasoned Lisp experts seldom use the textbook lambdas as can be seen in all Lisp books and that rank and file Lisp programmers use everywhere. Experts use macros because they understand their advantages (of which speed is an important one). Andrei
Re: Why Ruby?
On 12/19/10 11:21 AM, foobar wrote: Andrei Alexandrescu Wrote: On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); That does work. What doesn't work is calling nonmember functions looked up in the context of the caller. Andrei Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } is beautiful and clear. Besides, that return is bizarre - did you mean return from the comparison or the caller? Ruby chose the latter, which I think is very sensible, but in that case you have a more difficult time returning locally. Of course, inventing new syntax is always available :o). regarding hygiene - the term was correct. No. Andrei
Re: Optimizing delegates
On 12/19/10 11:23 AM, Ary Borenszweig wrote: On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ? Because that would be unlike everything else in D. Andrei
Re: Why Ruby?
On 12/19/10, foobar f...@bar.com wrote: This feature promotes a code smell. snip what happens in the following snippet? int a = 5; sort!a b(whatever); You've accurately described your snippet in advance. *That* is a code smell. You should never use single-variable names in your code in the first place.
Re: Why Ruby?
I meant single-letter variable names there. On 12/19/10, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 12/19/10, foobar f...@bar.com wrote: This feature promotes a code smell. snip what happens in the following snippet? int a = 5; sort!a b(whatever); You've accurately described your snippet in advance. *That* is a code smell. You should never use single-variable names in your code in the first place.
Re: Why Ruby?
On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:21 AM, foobar wrote: Andrei Alexandrescu Wrote: On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); That does work. What doesn't work is calling nonmember functions looked up in the context of the caller. Andrei Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } is beautiful and clear. Besides, that return is bizarre - did you mean return from the comparison or the caller? Ruby chose the latter, which I think is very sensible, but in that case you have a more difficult time returning locally. Not at all. The last executed statement is what gets returned. And that doesn't only apply to blocks, but to normal functions: def foo 1 end Of course, inventing new syntax is always available :o). regarding hygiene - the term was correct. No. Andrei
Re: Optimizing delegates
On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:23 AM, Ary Borenszweig wrote: On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ? Because that would be unlike everything else in D. Andrei What do you mean? It's not unlike everything else in D. It's *exactly* like a function call in D.
Re: emscripten
Adam D. Ruppe wrote: bearophile: On a more modern browser it works well enough (Firefox 4). This is a bit of a rant, but I hate how the web community always uses modern browser like this. I ran this site on Firefox 3.6.3. The most recent one it offers on getfirefox.com is 3.6.13 - I'm not very far behind! My about firefox box says Gecko from April 2010. That should be modern by any sane definition! (Now, my every day browser, Konqueror 3.5.7, is (c) 2005. So I can understand it not being a modern browser. But it works for me so I won't change it. Something I find hilarious though: it's CSS2 compliance was better than firefox up until about last year! I just wrote a site going wild with css for a web demo for the company, and it worked almost as well in my old Konq as it did in my newer Firefox. The kde folks did a really impressive job there.) Anyway, it just irks me that so many web evangelists say modern when they really mean bleeding edge. And in Google's case, it is even worse: when they say all modern browsers, they actually mean /our/ bleeding edge beta. It really annoys me. I'm more used to the term in every modern browser, except IE, in which case it is usually correct and modern means something from this or last year (except IE). Good old Konq from 2005 for example has better CSS2 support than IE8.
Re: Why Ruby?
Andrei Alexandrescu Wrote: Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. I reserve the right to dislike it even if it was 20 characters. The fact that it's a useful hack doesn't make it smell less. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } I wasn't referring to the above which still deals with the syntactic issue. I'm talking about making: sort!a b(whatever); and sort(whatever, (a, b) { return ab; }); have the same performance. Thus obviating the need for the first form. the best form IMO would be of course: whatever.sort((a, b) { return ab; }); This touches another topic - the universal function call feature.
Re: Why Ruby?
foobar wrote: ... I wasn't referring to the above which still deals with the syntactic issue. I'm talking about making: sort!a b(whatever); and sort(whatever, (a, b) { return ab; }); have the same performance. Thus obviating the need for the first form. the best form IMO would be of course: whatever.sort((a, b) { return ab; }); Would be nice, but: - is it even possible (performance-wise)? - can you enforce this performance constraint? There is a big difference between inlining a lexical closure and creating a full one on the heap. - with template alias parameters, its easy to compose more complex types at compile time, you will lose this ability.
Re: is it possible to learn D(2)?
On Sun, 19 Dec 2010 11:14:08 -0600 Andrei == Andrei Alexandrescu wrote: Andrei The thing is, however, that printed books still carry more Andrei authority than online ones, even though clearly there are many Andrei online books that compare favorably with the average printed Andrei book. I agree...For instance I bought Real World Haskell although it's available online for free. The only gripe I have about it is that it probably came too late for me. (I tried to learn Haskell before that.) Otoh, TDPL has come on time, I like it and, similarly, would buy it even if there would be free version online. Now, I'm happy being assured that D(2) can be learnt using TDPL. :-) Thanks to all for replies. ;) Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: CDBF17CA signature.asc Description: PGP signature
Re: Why Ruby?
On 2010-12-19 11:11:03 -0500, Jacob Carlborg d...@me.com said: On 2010-12-19 16:23, Andrei Alexandrescu wrote: On 12/19/10 6:26 AM, retard wrote: In case you didn't see, two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort in the sorting example) This can be solved by using a canonicalizer before passing to unaryFun. I considered doing that, but delayed implementing it to when this would actually become a problem. I can clearly see that you haven't used an Objective-C/D bridge. The reason (or at least one of the reasons) for which Michel Fortin (as well as I) gave up the Objective-C/D bridge and started to modify DMD is template bloat. I'm not saying that using template strings as lambdas is going to bloat your executable/library as much as the bridge does but I always think twice before adding a template to my code. Has anyone checked which of delegates or strings cause more template bloat? I'd suspect using strings will result in less bloat because the same string will often be reused (making the compiler reuse the same template instance) whereas the compiler will likely use the mangled name of the delegate when instantiating the template... and no two delegate literals have the same mangled name. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: is it possible to learn D(2)?
On 12/19/10, Gour g...@atmarama.net wrote: Now, I'm happy being assured that D(2) can be learnt using TDPL. :-) And if you get stuck with something don't hesitate asking about it in d-learn!
Re: Optimizing delegates
On 12/19/10 11:35 AM, Ary Borenszweig wrote: On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:23 AM, Ary Borenszweig wrote: On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ? Because that would be unlike everything else in D. Andrei What do you mean? It's not unlike everything else in D. It's *exactly* like a function call in D. No function definition expands into a template. Andrei
Re: Why Ruby?
On 12/19/10 11:31 AM, Ary Borenszweig wrote: On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:21 AM, foobar wrote: Andrei Alexandrescu Wrote: On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); That does work. What doesn't work is calling nonmember functions looked up in the context of the caller. Andrei Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } is beautiful and clear. Besides, that return is bizarre - did you mean return from the comparison or the caller? Ruby chose the latter, which I think is very sensible, but in that case you have a more difficult time returning locally. Not at all. The last executed statement is what gets returned. And that doesn't only apply to blocks, but to normal functions: def foo 1 end That would work if and only if it were designed into the language from day one - now it's too late. I encourage you to work out through various cases (if/else, switch, loops, returning void vs. a value) to see this will have considerable difficulties in D. Andrei
Re: Why Ruby?
On 12/19/10 11:54 AM, foobar wrote: Andrei Alexandrescu Wrote: Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. I reserve the right to dislike it even if it was 20 characters. The fact that it's a useful hack doesn't make it smell less. It doesn't smell. You believe it does only because you mistakenly believe it's not hygienic. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } I wasn't referring to the above which still deals with the syntactic issue. I'm talking about making: sort!ab(whatever); and sort(whatever, (a, b) { return ab; }); have the same performance. Thus obviating the need for the first form. I explained how this is much more difficult than it might seem at first sight. Andrei
Re: Optimizing delegates
On Sun, 19 Dec 2010 12:43:23 -0600 Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 12/19/10 11:35 AM, Ary Borenszweig wrote: On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:23 AM, Ary Borenszweig wrote: On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ? Because that would be unlike everything else in D. Andrei What do you mean? It's not unlike everything else in D. It's *exactly* like a function call in D. No function definition expands into a template. Andrei Don't you all find it annoying to constantly keep whole threads, most of which are to your answer irrelevant, just to reply a few word?. Please instead keep only relevant snippet(s). Here the kept text is about 5kb. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: is it possible to learn D(2)?
On Sun, 19 Dec 2010 19:35:52 +0100 Andrej == Andrej Mitrovic andrej.mitrov...@gmail.com wrote: Andrej Andrej And if you get stuck with something don't hesitate asking about Sure. Thanks. btw, it would be nice to have code examples from TDPL to save some typing. Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: CDBF17CA signature.asc Description: PGP signature
Re: Optimizing delegates
Ary Borenszweig a...@esperanto.org.ar wrote in message news:ieldl1$1of...@digitalmars.com... On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei foo.d --- import std.stdio; int foobar3(alias f)() { return f(1); } void main() { writefln(%d, foobar3!((x) { return 9876*x; })()); } aster...@deep-water:~/dmd2/linux/bin$ ./dmd foo.d -O -inline aster...@deep-water:~/dmd2/linux/bin$ ./obj2asm foo.o | vi - (line 530) _Dmain: push EBP mov EBP,ESP mov EAX,offset FLAT:_d3std5stdio6stdouts3std5stdio4f...@sym32 push dword ptr _t...@sym32[0eh] push dword ptr _t...@sym32[010h] push 02694h call _d3std5stdio4file19__t8writeflntayatiz8writeflnmfaya...@pc32 xor EAX,EAX pop EBP ret nop nop No, it doesn't seem to get inlined. Luckily. Because if it did get inlined then I would improve DMD by giving an error on this line: int foobar(int delegate(int) f) { ... } foo.d(3): Error: Hey man, what are you doing? Don't you know that if you pass delegates that way they don't get inlined? You should write it this way: int foobar(alias f)(). That is, of course, if you want your code to be more performant. It's not completely useless: int foobar(int delegate(int) f) { } allows you to choose what delegate to send at run-time. int foobar3(alias f)() { } doesn't. (Although, I suppose you might be able to work around that moving the run-time selection from the caller of foobar3 to the delegate passed into int foobar3(alias f)() { }. Not sure if there are cases where that would be awkward to do.) I will say though, it's a hell of a lot easier to remember the syntax of int foobar(alias f)(). :)
Re: Optimizing delegates
spir denis.s...@gmail.com wrote in message news:mailman.35.1292785009.4748.digitalmar...@puremagic.com... Don't you all find it annoying to constantly keep whole threads, most of which are to your answer irrelevant, just to reply a few word?. Please instead keep only relevant snippet(s). Here the kept text is about 5kb. Scrolling is very, very easy, and 5k is tiny.
Re: is it possible to learn D(2)?
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message news:ielekh$1qg...@digitalmars.com... Having a major publisher decide to take risks and invest money in producing at professional quality and marketing a book on a up-and-coming language is a clear signal that they believe in the success of the book and consequently that of the language. FWIW, if I'm trying to discern the quality or worth of a language, I wouldn't really consider a book publisher to be an authority on that any more than, say, a dentist. (Well, ok, maybe more than a dentist, but you get what I mean.)
Re: emscripten
Adam D. Ruppe destructiona...@gmail.com wrote in message news:ieleht$1qc...@digitalmars.com... bearophile: On a more modern browser it works well enough (Firefox 4). This is a bit of a rant, but I hate how the web community always uses modern browser like this. I ran this site on Firefox 3.6.3. The most recent one it offers on getfirefox.com is 3.6.13 - I'm not very far behind! My about firefox box says Gecko from April 2010. That should be modern by any sane definition! (Now, my every day browser, Konqueror 3.5.7, is (c) 2005. So I can understand it not being a modern browser. But it works for me so I won't change it. Something I find hilarious though: it's CSS2 compliance was better than firefox up until about last year! I just wrote a site going wild with css for a web demo for the company, and it worked almost as well in my old Konq as it did in my newer Firefox. The kde folks did a really impressive job there.) Anyway, it just irks me that so many web evangelists say modern when they really mean bleeding edge. And in Google's case, it is even worse: when they say all modern browsers, they actually mean /our/ bleeding edge beta. It really annoys me. Hear, hear!
Re: Why Ruby?
retard r...@tard.com.invalid wrote in message news:iejab1$2t...@digitalmars.com... As you can see, most of the verbosity comes from the fact that lambdas in D and C++ contain statements, not a single expression. It's like if-then- else vs ternary ?: -- In languages like Scala these are the same built-in feature. FWIW, I've always found if() else and other such constructs to be a bit verbose to use inside an expression. So I've always liked ?: (But I can certainly see the advantages of being able to use statements as expressions.)
Re: Why Ruby?
Andrej Mitrovic andrej.mitrov...@gmail.com wrote in message news:mailman.17.1292722525.4748.digitalmar...@puremagic.com... imo, those @'s (or monkeys, as we like to call them) are a sore pain in the eye. And what if you need to do some simple arithmetic with the numbered arguments? someFunc!(@1+1@2)(x); Might be a silly example, but code like this could exist and will be confusing. I had always liked the idea of something like @1,@2,etc or _1,_2,etc, but I think this is a completely convincing counter-argument.
Re: Why Ruby?
Jacob Carlborg d...@me.com wrote in message news:iel9p5$1go...@digitalmars.com... On 2010-12-19 01:01, Nick Sabalausky wrote: Walter Brightnewshou...@digitalmars.com wrote in message news:iejejo$pf...@digitalmars.com... Nick Sabalausky wrote: Any problem with the other Scala/C#-style one?: (x, y) = x * y // Lowered to: (x, y) { return x * y; } (Maybe that was rejected before due the the weird float operators that are now being ditched?) The problem with the (x,y) parameter lists, where x and y are the parameters, is that it is ambiguous with the existing syntax of (x,y) where x and y are types and the parameters are omitted. For example: void foo(int); But we already have: (x, y) { return x * y; } So either there aren't any problems with it after all, or D's existing delegate syntax is already broken. To be clear, with what I'm trying to suggest, the *only* thing that would be different from the current delegate literal syntax is that part *after* the parameter list. Ie: PARAM_LIST_HERE { return x * y; } // -- PARAM_LIST_HERE = x * y Or if there's a problem with =, then -, or --, or ::, or :, or whatever. I'm not suggesting the param list be different in any way fromhow t is now. (Although proposals from other people might differ.) ^^ Exactly. I would also like to have type inference for the parameter list, do we have that already in D2? I know you can use auto. I had thought you could also omit the type in a delegate literal's param list, but Walter's response above makes me think I might be mistaken. Even if so, as I was trying to say above, if delegate literals are indeed required to be (auto x, auto y) { return x * y; }, then I would be perfectly happy with lambdas that were the same: (auto x, auto y) = x * y I do think that's still far easier to read than the full delegate literal syntax.
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Max Samukha spam...@d-coding.com wrote in message news:iekuac$qr...@digitalmars.com... On 12/18/2010 10:03 PM, Nick Sabalausky wrote: Caligoiteronve...@gmail.com wrote in message news:mailman.5.1292651710.4588.digitalmar...@puremagic.com... IMO there is no honor in game development as it contributes nothing to society. I've rarely played any, I gotta jump on this as being a giant load of pretentous bullshit. First of all, there's the patently obvious how in the world would you know? considering the I've rarely played any. But more importantly, games make life suck less - I can't even imagine any more significant contribution to society than that. Even all of the endevors generally considered to be the biggest contributions to society are *only* significant contributions *because* that's exactly what they do: they make life suck less, and are therefore well-regarded. I hear you! People please legalize drugs. They make my life suck so much less. Assuming you meant that as a sarcastic counter-example: There may be ways in which they make life suck less, but *overall*, they're generally considered to make life suck *more*. So the make life suck less rule still holds. Although, if you meant it seriously then nevermind: The whole drug-legalization issue is one of the few debates I actively avoid :)
Re: Optimizing delegates
On Sun, 19 Dec 2010 14:14:08 -0500 Nick Sabalausky a...@a.a wrote: Don't you all find it annoying to constantly keep whole threads, most of which are to your answer irrelevant, just to reply a few word?. Please instead keep only relevant snippet(s). Here the kept text is about 5kb. Scrolling is very, very easy, and 5k is tiny. Scrolling pages and pages of useless text on every message just to find a few words: is no fun. 5kb * thousands of subscribers * thousands of messages/month * thousands of mailing lists: makes some weight. Anyway... (hears who is willing to hear) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Caligo iteronve...@gmail.com wrote in message news:mailman.30.1292776925.4748.digitalmar...@puremagic.com... You are absolutely right; life sucks for many people, and that's why some of them choose to play video games. It gives them a chance to escape reality, and game companies exploit this to make money. Game companies use all kinds of psychology in their games to keep you playing as long as possible. That is why to me there is no honor in game development. Also, I never said it's worthless; they make tons of money, and that's almost always at the expense of people like you. The old games as drugs argument. First of all, anyone who's a slave to psychological tricks is an idiot anyway. Casinos use many psychological tricks to induce addiction and yet most people are perfectly able to control themselves. Secondly, if you see movies, music, comics and novels as the same dishonorable escapism, then I'll grant that your reasoning is at least logically sound, even though you're in an extremely tiny minority on that viewpoint. If not, however, then you're whole argument crumbles into a giant pile of blatant bullshit, and clearly far too much of an imbicile to even continue discussing this with. If it helps any, I'm not one of those baby boomers. I'm actually in my early twenties. So if you are going to insult me at least do it properly. Fine, but that does make you the exception. You sound way too angry and unhappy. I just have no tolerance for such obvious lies and idiocy. Instead of playing video games, you should definitely pick up Ruby if you haven't already. I hear it's designed to make programmers happy. I realize you mean that in jest, but I actually have been using Ruby (Rake) as the build system for a big web project. It gets the job done, but I'm not exactly impressed with it.
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Christopher Nicholson-Sauls ibisbase...@gmail.com wrote in message news:iekles$79...@digitalmars.com... On 12/18/10 14:12, Nick Sabalausky wrote: Nick Sabalausky a...@a.a wrote in message news:iej46p$42...@digitalmars.com... Caligo iteronve...@gmail.com wrote in message news:mailman.5.1292651710.4588.digitalmar...@puremagic.com... IMO there is no honor in game development as it contributes nothing to society. I've rarely played any, I gotta jump on this as being a giant load of pretentious bullshit. First of all, there's the patently obvious how in the world would you know? considering the I've rarely played any. But more importantly, games make life suck less - I can't even imagine any more significant contribution to society than that. Even all of the endeavors generally considered to be the biggest contributions to society are *only* significant contributions *because* that's exactly what they do: they make life suck less, and are therefore well-regarded. Seriously, what up with all those presumptuous assholes out there (mostly baby boomer dinos and their even more anachronistic parents, interestingly enough) who have barely ever touched a videogame and yet figure they actually have reason to believe such absurd pretentious crap? Fuck, they all remind me of that pompous Roger Ebert douchebag. (Speaking of ways to benefit society, when's he finally gonna keel over? Isn't it about time by now? And speaking of contributions to society what the fuck's he ever done? Collect a salary just to spout off opinions? Fucking useless wanker.) Since it apparently isn't obvious to some people: things don't have to be dull to qualify as a significant a contribution. There's also the classic example: a game was instrumental in the development of UNIX. http://en.wikipedia.org/wiki/Space_Travel_(video_game) This wasn't arbitrary either; it was something Thompson wanted to do, and he needed a better OS to do it in... so his toy got new polish. Some of this polish became things we now take for granted and hardly know how to live without (like a hierarchial filesystem). Do I mean to say that without the game there would be no UNIX? No; but I do mean to say that games have *always* been a valuable tool for finding the limits of systems, and for inspiring innovative ways to expand those limits. The same research and development that provided pixel shaders to game developers, also provided them to medical imaging developers. The same that provided CPU technologies such as SSE to enable more complex simulations in games, also provide for more complex simulations in supercomputers. And many of these sort of technologies were original conceived just to make games more awesome. Amazing. So no, games in and of themselves don't contribute anything -- if you don't count fun, and honestly, I do count it -- but they have been a driving force behind a lot of innovation. Yea, and another thing is the matter of art in general: If you're an ultra-utilitarian like Christopher seems to be (and even most programmers aren't ultra-utilitarian), then art can be seen as lacking significant contribution to society. But if you do believe in the value of art and still cherry-pick videogames as dishonorable or lacking significant contribution, then you're just simply being a dumbfuck and an elitist (like Roger Ebert).
Re: emscripten
Adam D. Ruppe: Anyway, it just irks me that so many web evangelists say modern when they really mean bleeding edge. You are right, saying modern I have used the wrong words. If you use emscripten to compile large amounts of C or C++ code you probably need a very fast JavaScript engine. And we are still in the middle of the JS speed race, so it matters if you use FF 3.6 or FF4 or the latest canary build of Chrome that has Crankshaft. In few years this speed race will end and using the very latest JS engine will not matter. Bye, bearophile
Re: Why Ruby?
On 12/19/2010 03:45 PM, Andrei Alexandrescu wrote: On 12/19/10 11:31 AM, Ary Borenszweig wrote: On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:21 AM, foobar wrote: Andrei Alexandrescu Wrote: On 12/19/10 5:08 AM, foobar wrote: Walter Bright Wrote: JRM wrote: you could write: sort!(@1@2)(x); [...] I think this idea (or something similar) is worth consideration. It is simply a small extension to an already existing feature that would give D a terser syntax for lambda's than most of the other languages we've been discussing. but: sort!(ab)(x); is just as short! And it already works. I think that the issue here is not about syntax as much as it is about semantics: As others said, this is equivalent to dynamic language's eval() or to D's string mixin and the this raises the question of hygiene which sadly has no good solution in D. The main concern is this: In what context are the symbols 'a' and 'b' evaluated? At the moment they cannot be correctly evaluated at the caller context and do not allow: sort!(a.foo() b.bar())(whatever); That does work. What doesn't work is calling nonmember functions looked up in the context of the caller. Andrei Either way, I personally don't care that much for another syntax for delegates. I personally just want to see this ugly hack removed from the standard library and discouraged. This feature promotes a code smell. And for what, as you said yourself, to save 4 characters? a b vs. (a, b) { return a b; } Savings: 17 characters. D should be consistent with only ONE delegate syntax. This is why Ruby reads like poetry to its followers and c++ is like carving letters in stone. Also, Ruby is well slower than C++ and other languages. It's easy to design a beautiful language if that's the primary concern. It's difficult to design a language when you want to keep in harmony a larger list of desiderata. I much prefer that the lowering you mentioned to be implemented so that performance wise this UGLY hack will have no benefits. The lowering will unfortunately solve little. I don't see how sort!a b(array); is horrible but sort(a, b; array) { return a b; } is beautiful and clear. Besides, that return is bizarre - did you mean return from the comparison or the caller? Ruby chose the latter, which I think is very sensible, but in that case you have a more difficult time returning locally. Not at all. The last executed statement is what gets returned. And that doesn't only apply to blocks, but to normal functions: def foo 1 end That would work if and only if it were designed into the language from day one - now it's too late. I encourage you to work out through various cases (if/else, switch, loops, returning void vs. a value) to see this will have considerable difficulties in D. Andrei I was just pointing out that it works that way in Ruby, not that it should be implemented in D.
Re: Why Ruby?
On 2010-12-19 20:33, Nick Sabalausky wrote: retardr...@tard.com.invalid wrote in message news:iejab1$2t...@digitalmars.com... As you can see, most of the verbosity comes from the fact that lambdas in D and C++ contain statements, not a single expression. It's like if-then- else vs ternary ?: -- In languages like Scala these are the same built-in feature. FWIW, I've always found if() else and other such constructs to be a bit verbose to use inside an expression. So I've always liked ?: (But I can certainly see the advantages of being able to use statements as expressions.) There are other places where they can be useful, like initializing variables: auto y = if (x == 3) 4; else 5; In this simple case the ternary operator would of course be better to use. -- /Jacob Carlborg
Re: Why Ruby?
On 2010-12-19 19:29, Michel Fortin wrote: On 2010-12-19 11:11:03 -0500, Jacob Carlborg d...@me.com said: On 2010-12-19 16:23, Andrei Alexandrescu wrote: On 12/19/10 6:26 AM, retard wrote: In case you didn't see, two additional problems were also listed earlier in this thread: - template bloat (different strings generate new instances of the sort in the sorting example) This can be solved by using a canonicalizer before passing to unaryFun. I considered doing that, but delayed implementing it to when this would actually become a problem. I can clearly see that you haven't used an Objective-C/D bridge. The reason (or at least one of the reasons) for which Michel Fortin (as well as I) gave up the Objective-C/D bridge and started to modify DMD is template bloat. I'm not saying that using template strings as lambdas is going to bloat your executable/library as much as the bridge does but I always think twice before adding a template to my code. Has anyone checked which of delegates or strings cause more template bloat? I'd suspect using strings will result in less bloat because the same string will often be reused (making the compiler reuse the same template instance) whereas the compiler will likely use the mangled name of the delegate when instantiating the template... and no two delegate literals have the same mangled name. That would only be the case if the function takes the delegate as a template parameter? -- /Jacob Carlborg
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Adam D. Ruppe wrote: Patrick Down wrote: bearophile Wrote: Yet I hope Walter will not waste 6 hours every day *playing* World of warcraft :-) He does however write games sometimes: http://www.classicempire.com/ I've never played WoW, but I have played Empire, and let me tell you, it wastes a lot more than 6 hours a day! Yes, Empire has been blamed for many students flunking out of university, and at least one divorce!
Re: Game development is worthless? WTF? (Was: Why Ruby?)
On Sun, Dec 19, 2010 at 5:41 PM, Caligo iteronve...@gmail.com wrote: You are absolutely right; life sucks for many people, and that's why some of them choose to play video games. It gives them a chance to escape reality, and game companies exploit this to make money. Game companies use all kinds of psychology in their games to keep you playing as long as possible. That is why to me there is no honor in game development. This is bullshit. Of course there are games with that goal (WoW, ...), but this doesn't make game development in general unhonorable. There are many games that are not like this, for example most single player only games.. you play them until the end or until you can't get any further and that's it.. maybe you play them again in the future, but it's not like a constant addiction. (I'm not saying that multi player games are generally more dangerous or anything, single player games are just an example everybody should be able to comprehend) There are also game developers who openly label games like WoW unethical, e.g. http://en.wikipedia.org/wiki/Jonathan_Blow
Re: Optimizing delegates
On 12/19/2010 03:43 PM, Andrei Alexandrescu wrote: On 12/19/10 11:35 AM, Ary Borenszweig wrote: On 12/19/2010 02:28 PM, Andrei Alexandrescu wrote: On 12/19/10 11:23 AM, Ary Borenszweig wrote: On 12/19/2010 02:17 PM, Andrei Alexandrescu wrote: On 12/19/10 11:13 AM, Ary Borenszweig wrote: On 12/19/2010 01:44 PM, Andrei Alexandrescu wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei This of course has the following problem: int foobar2(int delegate(int x) f) { } foobar2((int x, int y) { ... }); Error: function foobar2 (int delegate(int) f) is not callable using argument types (int delegate(int x, int y)) --- int foobar3(alias f)() { f(1); } foobar3((x, y) { ... }); foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) does not match any function template declaration foo.d(8): Error: template foo.main.__dgliteral1(__T2,__T3) cannot deduce template function from argument types !()(int) foo.d(12): Error: template instance foo.main.foobar3!(__dgliteral1) error instantiating So I have to go to foo.d(8) to see what the problem is, understand what is being invoked (in this case it was easy but it get can harder), or otherwise say Hey, the one that implemented foo, please do a static assert msg if f is not what you expect. Basically Implement the error message that the compiler would have given you for free if you didn't use a template. Template constraints are meant to assuage that problem. Inlining delegates is technically much more difficult than inlining aliases. This is because a different function will be generated for each alias argument, whereas only one function would be used for all delegates. There are techniques to address that in the compiler, but they are rather complex. Andrei I understand. So why do I have to use a whole different syntax to make something accepting a delegate a function or a template? Why can't this be accepted? int foobar2(int delegate(int x) f)() { } and let the compiler interpret it as: int foobar2(alias f) if (the correct constraint which I don't want to learn how to write because the above SHOULD work) { } ? Because that would be unlike everything else in D. Andrei What do you mean? It's not unlike everything else in D. It's *exactly* like a function call in D. No function definition expands into a template. Andrei But that is a template: int foobar2(int delegate(int x) f)() { } It's a template that doesn't work because I have to write it in a different way. Sorry, I tried many different template constraints and none of them work. I tried these: int foobar2(alias f)() if (typeof(f) == typeid(int delegate(int x))) if (is(typeof(f) == int delegate(int))) if (is(typeof(f) == delegate)) What do I have to write to make it work?
Re: Why Ruby?
Ary Borenszweig wrote: Imagine you don't have to write semicolons in D. If you have 1000 lines of code you save 1000 keystrokes and characters to read. If you have about 50 delegates in your code you save 200 characters. I don't think this is more important than the other problems you mention, but adding bits of characters here and there ends up saving a lot. Saving keystrokes is, in my not so humble opinion, a totally bogus metric with which to judge a programming language. What matters, in anything other than a language designed for one-liners, is how the code looks on the page. For example, we don't just nail photo prints to the wall. We present them with a matte, then mount in a complementary frame. Cooking is a lot about the presentation of the food, not just the taste. I think that source code is a lot about the presentation of it. It should look good. The way it looks should be an aid to understanding what it does. Correct code should look right, wrong code should look wrong. (I've had many experience programmers tell me they can just scan a page of code and the bugs stand out because they just look wrong. They don't have to actually understand the code to find the bugs. A language that enhances this effect is a better language than one that does not.) For example, it's hard to format code with goto's so it looks right. It's a lot easier with structured constructs. There is value in brevity - extra syntactical noise can distract from what the code is doing. But it can also positively frame and present code. That's what should be the criteria.
Re: Optimizing delegates
On Sun, Dec 19, 2010 at 5:44 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 12/19/10 10:35 AM, Ary Borenszweig wrote: On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: On 12/19/10 9:32 AM, Ary Borenszweig wrote: I have this code: --- import std.stdio; int foobar(int delegate(int) f) { return f(1); } int foobar2(string s)() { int x = 1; mixin(return ~ s ~ ;); } void main() { writefln(%d, foobar((int x) { return 2*x; })); writefln(%d, foobar2!(9876*x)); } --- When I compile it with -O -inline I can see with obj2asm that for the first writefln the delegate is being called. However, for the second it just passes 9876 to writefln. From this I can say many things: - It seems that if I want hyper-high performance in my code I must use string mixins because delegate calls, even if they are very simple and the functions that uses them are also very simple, are not inlined. This has the drawback that each call to foobar2 with a different string will generate a different method in the object file. You forgot: writefln(%d, foobar2!((x) { return 2*x; })()); That's a real delegate, not a string, but it will be inlined. Andrei Sorry, I don't understand. I tried these: 1. int foobar3(int delegate(int) f)() { return f(1); } writefln(%d, foobar3!((int x) { return 2*x; })()); = foo.d(12): Error: arithmetic/string type expected for value-parameter, not int delegate(int) 2. int foobar3()(int delegate(int) f) { return f(1); } writefln(%d, foobar3!()((int x) { return 2*x; })); = Works, but it doesn't get inlined. And I tried that (x) { ... } syntax and it doesn't work. Sorry, it must be my fault I'm doing something wrong. What's the correct way of writing optimized code in D, code that I'm sure the compiler will know how to optimize? void foobar3(alias fun)() { return fun(1); } Andrei I think using an alias makes the code less readable. int foobar(int delegate(int) f) tells you that the argument should be (a delegate of) a function that accepts an int and returns an int. foobar3(alias fun)() tells you almost nothing. You know that some kind of template parameter is expected, but not if it's a function or whatever, and even less what signature that function should have. IMHO some other syntax than just alias fun should be used for this purpose (inlined delegates known at compile time) - some syntax that documents the signature of the expected function, like with real delegates. Cheers, - Daniel
Re: Game development is worthless? WTF? (Was: Why Ruby?)
Daniel Gibson metalcae...@gmail.com wrote in message news:mailman.37.1292790264.4748.digitalmar...@puremagic.com... On Sun, Dec 19, 2010 at 5:41 PM, Caligo iteronve...@gmail.com wrote: You are absolutely right; life sucks for many people, and that's why some of them choose to play video games. It gives them a chance to escape reality, and game companies exploit this to make money. Game companies use all kinds of psychology in their games to keep you playing as long as possible. That is why to me there is no honor in game development. This is bullshit. Of course there are games with that goal (WoW, ...), but this doesn't make game development in general unhonorable. There are many games that are not like this, for example most single player only games.. you play them until the end or until you can't get any further and that's it.. maybe you play them again in the future, but it's not like a constant addiction. (I'm not saying that multi player games are generally more dangerous or anything, single player games are just an example everybody should be able to comprehend) There are also game developers who openly label games like WoW unethical, e.g. http://en.wikipedia.org/wiki/Jonathan_Blow Interesting. I don't think I would go so far as to claim that WoW was unethical...just uninteresting ;) But that's just me. This is at least one thing the videogame world does that I do consider unethical: Proprietary/Closed platforms. But that's not just a videogame thing, of course. I consider proprietary/closed platforms in general to be unethical. (Oh crap, I think I can feel myself turning into Stallman!)