digitalmars.D.announce - dmd 2.029 release
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- "Simen Kjaeraas" <simen.kjaras gmail.com> Apr 20 2009
- BCS <none anon.com> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- Russell Lewis <webmaster villagersonline.com> Apr 19 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- bearophile <bearophileHUGS lycos.com> Apr 20 2009
- BCS <ao pathlink.com> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- "Nick Sabalausky" <a a.a> Apr 20 2009
- BCS <ao pathlink.com> Apr 20 2009
- "Nick Sabalausky" <a a.a> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Russell Lewis <webmaster villagersonline.com> Apr 20 2009
- Lutger <lutger.blijdestijn gmail.com> Apr 21 2009
- "Nick Sabalausky" <a a.a> Apr 20 2009
- renoX <renosky free.fr> Apr 27 2009
- "Nick Sabalausky" <a a.a> Apr 27 2009
- renoX <renosky free.fr> Apr 27 2009
- Daniel Keep <daniel.keep.lists gmail.com> Apr 20 2009
- Daniel Keep <daniel.keep.lists gmail.com> Apr 20 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- tama <repeatedly gmail.com> Apr 20 2009
- tama <repeatedly gmail.com> Apr 20 2009
- "Denis Koroskin" <2korden gmail.com> Apr 20 2009
- tama <repeatedly gmail.com> Apr 20 2009
- "Saaa" <empty needmail.com> Apr 20 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- Tomas Lindquist Olsen <tomas.l.olsen gmail.com> Apr 20 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- dsimcha <dsimcha yahoo.com> Apr 20 2009
- dsimcha <dsimcha yahoo.com> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- "Craig Black" <craigblack2 cox.net> Apr 20 2009
- superdan <super dan.org> Apr 20 2009
- downs <default_357-line yahoo.de> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 20 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- Leandro Lucarella <llucax gmail.com> Apr 21 2009
- Georg Wrede <georg.wrede iki.fi> Apr 20 2009
- Russell Lewis <webmaster villagersonline.com> Apr 19 2009
- annoyed <abc email.com> Apr 20 2009
- Tyro[a.c.edwards] <nospam home.com> Apr 20 2009
- Stewart Gordon <smjg_1998 yahoo.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- BCS <none anon.com> Apr 20 2009
- Walter Bright <newshound1 digitalmars.com> Apr 20 2009
- Stewart Gordon <smjg_1998 yahoo.com> Apr 21 2009
- Walter Bright <newshound1 digitalmars.com> Apr 27 2009
- Sean Kelly <sean invisibleduck.org> Apr 27 2009
- Max Samukha <samukha voliacable.com.removethis> Apr 20 2009
- Max Samukha <samukha voliacable.com.removethis> Apr 21 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 21 2009
- Max Samukha <samukha voliacable.com.removethis> Apr 22 2009
- Max Samukha <samukha voliacable.com.removethis> Apr 22 2009
- Brad Roberts <braddr puremagic.com> Apr 22 2009
- "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> Apr 21 2009
- Frits van Bommel <fvbommel REMwOVExCAPSs.nl> Apr 21 2009
- Daniel Keep <daniel.keep.lists gmail.com> Apr 21 2009
- Frits van Bommel <fvbommel REMwOVExCAPSs.nl> Apr 21 2009
- Lutger <lutger.blijdestijn gmail.com> Apr 21 2009
- Don <nospam nospam.com> Apr 21 2009
- Lutger <lutger.blijdestijn gmail.com> Apr 21 2009
- Walter Bright <newshound1 digitalmars.com> Apr 21 2009
- Georg Wrede <georg.wrede iki.fi> Apr 21 2009
- Don <nospam nospam.com> Apr 22 2009
- Georg Wrede <georg.wrede iki.fi> Apr 22 2009
- Don <nospam nospam.com> Apr 22 2009
- Georg Wrede <georg.wrede iki.fi> Apr 23 2009
- Charles Hixson <charleshixsn earthlink.net> Apr 23 2009
- Sean Kelly <sean invisibleduck.org> Apr 22 2009
- Walter Bright <newshound1 digitalmars.com> Apr 27 2009
- Leandro Lucarella <llucax gmail.com> Apr 22 2009
- Walter Bright <newshound1 digitalmars.com> Apr 27 2009
- Walter Bright <newshound1 digitalmars.com> Apr 27 2009
- Christopher Wright <dhasenan gmail.com> Apr 27 2009
- Georg Wrede <georg.wrede iki.fi> Apr 28 2009
- Walter Bright <newshound1 digitalmars.com> Apr 28 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 21 2009
- "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> Apr 21 2009
- Leandro Lucarella <llucax gmail.com> Apr 21 2009
- Lutger <lutger.blijdestijn gmail.com> Apr 21 2009
- Don <nospam nospam.com> Apr 21 2009
- bearophile <bearophileHUGS lycos.com> Apr 21 2009
- bearophile <bearophileHUGS lycos.com> Apr 21 2009
- bearophile <bearophileHUGS lycos.com> Apr 21 2009
- Don <nospam nospam.com> Apr 21 2009
- Don <nospam nospam.com> Apr 21 2009
- bearophile <bearophileHUGS lycos.com> Apr 21 2009
- Don <nospam nospam.com> Apr 21 2009
- Don <nospam nospam.com> Apr 22 2009
- bearophile <bearophileHUGS lycos.com> Apr 22 2009
- bearophile <bearophileHUGS lycos.com> Apr 22 2009
- Don <nospam nospam.com> Apr 23 2009
- bearophile <bearophileHUGS lycos.com> Apr 23 2009
- Don <nospam nospam.com> Apr 23 2009
- Don <nospam nospam.com> Apr 25 2009
- Michel Fortin <michel.fortin michelf.com> Apr 21 2009
- Daniel Keep <daniel.keep.lists gmail.com> Apr 21 2009
- Don <nospam nospam.com> Apr 22 2009
- Don <nospam nospam.com> Apr 22 2009
- Tomas Lindquist Olsen <tomas.l.olsen gmail.com> Apr 23 2009
- Don <nospam nospam.com> Apr 21 2009
- Tomas Lindquist Olsen <tomas.l.olsen gmail.com> Apr 21 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 22 2009
- tama <repeatedly gmail.com> Apr 21 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Apr 22 2009
- "Masahiro Nakagawa" <repeatedly gmail.com> Apr 22 2009
- "Masahiro Nakagawa" <repeatedly gmail.com> Apr 22 2009
- "Masahiro Nakagawa" <repeatedly gmail.com> Apr 23 2009
This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Apr 20 2009
On Mon, 20 Apr 2009 09:09:09 +0200, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Butbutbut... I've just barely managed to install 2.028 yet. Great work! Can't wait to try out the new ranges. -- Simen
Apr 20 2009
Hello Walter,This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Cool template function literals sounds interesting
Apr 20 2009
BCS Wrote:Cool template function literals sounds interesting
May I have one example of them? I am looking in the docs, but I am not finding anything... Bye, bearophile
Apr 20 2009
bearophile wrote:BCS Wrote:Cool template function literals sounds interesting
May I have one example of them? I am looking in the docs, but I am not finding anything...
void foo(alias f)() { f(3, 4); } foo!((x,y){return x * y;))();
Apr 20 2009
Walter Bright:void foo(alias f)() { f(3, 4); } foo!((x,y){return x * y;))();
I have tried: import std.stdio: writeln; void foo(alias f)() { f(3, 4); } void main() { foo!( (x, y) { writeln(x * y); } )(); } And it works, printing 12 :-) Very cute. This is able to simplify some of the code of (D1) dlibs :-) I didn't even know that lambda delegates in D2 can now infer the type of their input argument, so you can use (x, y) instead of (int x, int y). Can you tell me when this was changed? :-) Bye, bearophile
Apr 20 2009
In D1 I have written a very hairy (but not too much long) apply() function,
that given a function and some arguments, returns the result of the function
applied to them. (apply() is a basic higher-order thing common in most
functional languages).
So now I'm playing with this new toy of D2, not using it in a serious way yet,
and I have written:
import std.stdio: writeln;
auto apply(alias f, TyArgs...)(TyArgs args) {
return f(args);
}
void main() {
writeln( apply!( (x, y) { return x * y; } )(3, 4) );
}
But when I compile it the compile spits out at compile-time:
Assertion failure: '0' on line 935 in file 'glue.c'
Bye,
bearophile
Apr 20 2009
bearophile wrote:In D1 I have written a very hairy (but not too much long) apply() function, that given a function and some arguments, returns the result of the function applied to them. (apply() is a basic higher-order thing common in most functional languages). So now I'm playing with this new toy of D2, not using it in a serious way yet, and I have written: import std.stdio: writeln; auto apply(alias f, TyArgs...)(TyArgs args) { return f(args); } void main() { writeln( apply!( (x, y) { return x * y; } )(3, 4) ); } But when I compile it the compile spits out at compile-time: Assertion failure: '0' on line 935 in file 'glue.c' Bye, bearophile
Your code should work as expected. (Also, right off the bat, any assertion failure in the compiler is a bug.) Could you submit to bugzilla? Andrei
Apr 20 2009
bearophile wrote:Assertion failure: '0' on line 935 in file 'glue.c'
All assertion failures are compiler bugs and belong in bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=2863
Apr 20 2009
bearophile wrote:I didn't even know that lambda delegates in D2 can now infer the type of their input argument, so you can use (x, y) instead of (int x, int y). Can you tell me when this was changed? :-)
That change *is* the template function literals, and they are only valid as template arguments.
Apr 20 2009
tama:void foo(alias f)() { writefln(f(3, 4)); } foo!((x,y){ return x * y; })(); This code doesn't work(compile error).
To me the following works: import std.stdio: writeln; void foo(alias f)() { writeln(f(3, 4)); } void main() { foo!((x,y){ return x * y; })(); } Bye, bearophile
Apr 20 2009
tama wrote:I tested following code. writefln(3 * 4); This code doesn't work in the first place:-<
Yes, that's one of the breaking changes in the new phobos2. writefln expects its first argument to be a format string. If it isn't, use writeln instead.
Apr 20 2009
Walter Bright wrote:tama wrote:I tested following code. writefln(3 * 4); This code doesn't work in the first place:-<
Yes, that's one of the breaking changes in the new phobos2. writefln expects its first argument to be a format string. If it isn't, use writeln instead.
I just hit the same breakage. :( Since the compiler can detect this situation statically, shouldn't Phobos just statically redirect the call to writeln() ?
Apr 19 2009
Russell Lewis wrote:Walter Bright wrote:tama wrote:I tested following code. writefln(3 * 4); This code doesn't work in the first place:-<
Yes, that's one of the breaking changes in the new phobos2. writefln expects its first argument to be a format string. If it isn't, use writeln instead.
I just hit the same breakage. :( Since the compiler can detect this situation statically, shouldn't Phobos just statically redirect the call to writeln() ?
It did for a while. For cleanliness purposes, I thought it was about time to eliminate that. Also, extraneous arguments passed to writef will be ignored, not printed with default formatting. Andrei
Apr 20 2009
Andrei Alexandrescu:extraneous arguments passed to writef will be ignored, not printed with default formatting.
That sounds bad: => "Errors should never pass silently." It's better to raise a compilation error. (And if that's not possible, then an exception at run-time. But a compilation error is much better). Bye, bearophile
Apr 20 2009
bearophile wrote:Andrei Alexandrescu:extraneous arguments passed to writef will be ignored, not printed with default formatting.
That sounds bad: => "Errors should never pass silently." It's better to raise a compilation error. (And if that's not possible, then an exception at run-time. But a compilation error is much better).
If it were an error, I wouldn't let it go. A good use case is string tables - a formatted message may or may not use all of the available information. Andrei
Apr 20 2009
Andrei Alexandrescu:If it were an error, I wouldn't let it go.
It's an error. It will lead to troubles. Bye, bearophile
Apr 20 2009
Reply to bearophile,Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Bye, bearophile
Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error. One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
Apr 20 2009
BCS wrote:Reply to bearophile,Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Bye, bearophile
Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error. One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
Yah, that's an option I considered. Maybe it's the best way to go. Andrei
Apr 20 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:gsiqdr$1csj$2 digitalmars.com...BCS wrote:Reply to bearophile,Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Bye, bearophile
Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error. One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
Yah, that's an option I considered. Maybe it's the best way to go.
That would be far too clumbsy, unless you made it into two separate functions. For instance (psuedocode): auto userInput = getUserInput() // userInput now contains "{Name} at {Address}", zip deliberately ignored writefln(userInput, name, address, zip); // They're used in-order, but there shouldn't be an error
Apr 20 2009
Reply to Nick,"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:gsiqdr$1csj$2 digitalmars.com...BCS wrote:One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
functions. For instance (psuedocode): auto userInput = getUserInput() // userInput now contains "{Name} at {Address}", zip deliberately ignored writefln(userInput, name, address, zip); // They're used in-order, but there shouldn't be an error
They are in order but are listed by name so the error doesn't throw. The case where the error would be thrown is where the only format strings used are the "get the next arg" kind.
Apr 20 2009
"BCS" <ao pathlink.com> wrote in message news:78ccfa2d3e68b8cb8fe69f8b7fba news.digitalmars.com...Reply to Nick,"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:gsiqdr$1csj$2 digitalmars.com...BCS wrote:One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
functions. For instance (psuedocode): auto userInput = getUserInput() // userInput now contains "{Name} at {Address}", zip deliberately ignored writefln(userInput, name, address, zip); // They're used in-order, but there shouldn't be an error
They are in order but are listed by name so the error doesn't throw. The case where the error would be thrown is where the only format strings used are the "get the next arg" kind.
I was just using names for illustrative purposes. Also, I was under the impression that printf-style "get the next arg" formatting codes were the only ones writef supported. Is this not so?
Apr 20 2009
Nick Sabalausky wrote:"BCS" <ao pathlink.com> wrote in message news:78ccfa2d3e68b8cb8fe69f8b7fba news.digitalmars.com...Reply to Nick,"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:gsiqdr$1csj$2 digitalmars.com...BCS wrote:One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
functions. For instance (psuedocode): auto userInput = getUserInput() // userInput now contains "{Name} at {Address}", zip deliberately ignored writefln(userInput, name, address, zip); // They're used in-order, but there shouldn't be an error
case where the error would be thrown is where the only format strings used are the "get the next arg" kind.
I was just using names for illustrative purposes. Also, I was under the impression that printf-style "get the next arg" formatting codes were the only ones writef supported. Is this not so?
Since a few versions ago writef supports positional arguments with Posix syntax. Andrei
Apr 20 2009
Andrei Alexandrescu wrote:Nick Sabalausky wrote:"BCS" <ao pathlink.com> wroteReply to Nick,"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:gsiqdr$1csj$2 digitalmars.com...BCS wrote:One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
functions. For instance (psuedocode): auto userInput = getUserInput() // userInput now contains "{Name} at {Address}", zip deliberately ignored writefln(userInput, name, address, zip); // They're used in-order, but there shouldn't be an error
The case where the error would be thrown is where the only format strings used are the "get the next arg" kind.
the impression that printf-style "get the next arg" formatting codes were the only ones writef supported. Is this not so?
syntax. Andrei
Positional format specifications really make a huge difference, especially where one needs to have the user interface in several languages. Thanks for them!! Now, for the case without positional format specifications, we could (and I guess, should) have a solution to "the wrong number of arguments" problem. If we have: - a non-printing format spec - a munch-the-remaining-ones format spec - an ignore-too-few-arguments format spec we could cover all the needed cases. The first one lets you use one parameter without printing it. (Maybe you don't want to print the middle part of somebody's name.) The second is used when you don't want to print possibly many remaining arguments, say the address of someone, or the country. The last one, is for the case where you use a single format string in several contexts, some of which you suspect may not contain enough information to be formally correct, but where you are satisfied to print an empty string '' (that is, not print anything) for them. This situation might arise when the format string originates from outside the program. ** When none of the latter two are used, and there is the wrong number of arguments, I think a runtime exception should be thrown. The only time where I think a compile time error is warranted, is when the format string is a string literal, with the wrong number of arguments. The programmer may put the ignore-too-few-arguments format spec anywhere in the format string. Its effect starts from that point on.
Apr 20 2009
bearophile wrote:Andrei Alexandrescu:If it were an error, I wouldn't let it go.
It's an error. It will lead to troubles.
Well at most you could say it's error-prone, something that is easier to argue. The problem is that forcing it into an error makes quite a number of valid uses impossible. An example is a logging application that provides you a number of pieces of information (date, time, message, etc.) and you get to specify how they should be formatted. Oftentimes you'd choose to ignore some data. Andrei
Apr 20 2009
Andrei Alexandrescu wrote:bearophile wrote:Andrei Alexandrescu:If it were an error, I wouldn't let it go.
It's an error. It will lead to troubles.
Well at most you could say it's error-prone, something that is easier to argue. The problem is that forcing it into an error makes quite a number of valid uses impossible. An example is a logging application that provides you a number of pieces of information (date, time, message, etc.) and you get to specify how they should be formatted. Oftentimes you'd choose to ignore some data. Andrei
Fair enough. But then let's split off a version of the function which allows unused arguments. For most users, in most cases, unused arguments are indicative of an error. Case in point: I have been bitten by this perhaps half a dozen times *already* porting older code. This code used to work fine: writefln("The value is: %d", myVar, ". Do something!"); Now, it interprets the trailing string as an unused argument, and ignores it (silently). Ugh. Ofc, looking back, I don't like that old coding style...I'm migrating back more to C-style (give the whole format string first). But the fact that I had a *silent* error was frustrating. Russ
Apr 20 2009
Russell Lewis wrote: ...Case in point: I have been bitten by this perhaps half a dozen times *already* porting older code. This code used to work fine: writefln("The value is: %d", myVar, ". Do something!");
I bet a lot of to-be-ported D code will have this bug, I know my code will. When you want to print a format string this way - last argument(s) simply appended, it saves you two characters typing. When something saves any characters typing and produces the same result, programmers will do that.
Apr 21 2009
"bearophile" <bearophileHUGS lycos.com> wrote in message news:gsipn1$1bng$1 digitalmars.com...Andrei Alexandrescu:If it were an error, I wouldn't let it go.
It's an error. It will lead to troubles.
Sometimes it is an error, but there are times when it isn't: Suppose you're writing a reporting module for an employee database: --------------------- ID: 3234 Last: Doe First: John Phone: 555-5555 Zip: 90210 ID: 7642 Last: Smith Etc... --------------------- And you want the admins to be able to define their own reports: --------------------- Privileged Report: For Each Person: "ID #{ID}\nName: {First} {Last}\nPhone: {Phone}\nZip:{Zip}" Unprivileged Report: For Each Person: "Name: {Last}, {First}\nContact Info Classified" Call List In Psuedo-Japanese: For Each Person Where Name="Smith": "SmithSan {LoopIndex}'s DenwaBango: {Phone}" --------------------- So then the report creation code: --------------------- foreach(int i, Person p; people.subset(customReport.whereClause)) writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip); --------------------- That would be very difficult/limiting if every arg had to be used in the format string. (Incidentally, this example also demonstrates why I consider C#/Tango-style string formatting superior to C/Phobos-style)
Apr 20 2009
Nick Sabalausky a écrit :"bearophile" <bearophileHUGS lycos.com> wrote in message news:gsipn1$1bng$1 digitalmars.com...Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Sometimes it is an error, but there are times when it isn't:
Call List In Psuedo-Japanese: For Each Person Where Name="Smith": "SmithSan {LoopIndex}'s DenwaBango: {Phone}" --------------------- So then the report creation code: --------------------- foreach(int i, Person p; people.subset(customReport.whereClause)) writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip); --------------------- That would be very difficult/limiting if every arg had to be used in the format string.
Mmmh, is {LoopIndex} correct? It should be {i} I think and I would argue that this format string should generate an error (something better than a runtime exception would be nice but I'm not sure that this is possible). That said I agree that both are needed, so why not have either two different function or a function parameter which change the behaviour of the format string interpretation? By default writefln would complain if there is a possibility of an unused parameter, but you could do writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip, allowUnused=true);(Incidentally, this example also demonstrates why I consider C#/Tango-style string formatting superior to C/Phobos-style)
I think that named format string are much superior to positional format string as they are easier to read/write.. BR, renoX
Apr 27 2009
"renoX" <renosky free.fr> wrote in message news:49F56A74.4000606 free.fr...Nick Sabalausky a écrit :"bearophile" <bearophileHUGS lycos.com> wrote in message news:gsipn1$1bng$1 digitalmars.com...Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Sometimes it is an error, but there are times when it isn't:
Call List In Psuedo-Japanese: For Each Person Where Name="Smith": "SmithSan {LoopIndex}'s DenwaBango: {Phone}" --------------------- So then the report creation code: --------------------- foreach(int i, Person p; people.subset(customReport.whereClause)) writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip); --------------------- That would be very difficult/limiting if every arg had to be used in the format string.
Mmmh, is {LoopIndex} correct? It should be {i} I think and I would argue that this format string should generate an error (something better than a runtime exception would be nice but I'm not sure that this is possible).
That was just for illustrative purposes.(Incidentally, this example also demonstrates why I consider C#/Tango-style string formatting superior to C/Phobos-style)
I think that named format string are much superior to positional format string as they are easier to read/write..
Actually, I was referring to the ability to specify them out-of-order, repeat them, etc. (I didn't realize that Phobos's writef had recently gained that ability). To my knowledge, C#/Tango string formatting don't actually support named strings, only numerical ones. I was just using names for illustrative purposes, and (unclearly) implying that the app would translate those named formats into numerical ones before passing them along to the string output function.
Apr 27 2009
Nick Sabalausky a écrit :"bearophile" <bearophileHUGS lycos.com> wrote in message news:gsipn1$1bng$1 digitalmars.com...Andrei Alexandrescu:If it were an error, I wouldn't let it go.
Sometimes it is an error, but there are times when it isn't:
Call List In Psuedo-Japanese: For Each Person Where Name="Smith": "SmithSan {LoopIndex}'s DenwaBango: {Phone}" --------------------- So then the report creation code: --------------------- foreach(int i, Person p; people.subset(customReport.whereClause)) writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip); --------------------- That would be very difficult/limiting if every arg had to be used in the format string.
Mmmh, is {LoopIndex} correct? It should be {i} I think and I would argue that this format string should generate an error (something better than a runtime exception would be nice but I'm not sure that this is possible). That said I agree that both are needed, so why not have either two different function or a function parameter which change the behaviour of the format string interpretation? By default writefln would complain if there is a possibility of an unused parameter, but you could do writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone, p.zip, allowUnused=true);(Incidentally, this example also demonstrates why I consider C#/Tango-style string formatting superior to C/Phobos-style)
I think that named format string are much superior to positional format string as they are easier to read/write.. BR, renoX
Apr 27 2009
bearophile wrote:BCS Wrote:Cool template function literals sounds interesting
May I have one example of them? I am looking in the docs, but I am not finding anything... Bye, bearophile
If I had to guess, I'd say it was something like this:alias (T)(T a, T b) { return (a+b)/2.0; } average;
Haven't had a chance to TRY that yet, mind you. :P -- Daniel
Apr 20 2009
Daniel Keep wrote:bearophile wrote:BCS Wrote:Cool template function literals sounds interesting
I am looking in the docs, but I am not finding anything... Bye, bearophile
If I had to guess, I'd say it was something like this:alias (T)(T a, T b) { return (a+b)/2.0; } average;
Haven't had a chance to TRY that yet, mind you. :P -- Daniel
(Sees Walter's post) Guess not. :P -- Daniel
Apr 20 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Ooohhh, just half way through the change log, and already breathless!!!
Apr 20 2009
On Mon, 20 Apr 2009 18:12:16 +0900, Walter Bright <newshound1 digitalmars.com> wrote:bearophile wrote:BCS Wrote:Cool template function literals sounds interesting
I am looking in the docs, but I am not finding anything...
void foo(alias f)() { f(3, 4); } foo!((x,y){return x * y;))();
void foo(alias f)() { writefln(f(3, 4)); } foo!((x,y){ return x * y; })(); This code doesn't work(compile error). But, following code works. void bar(alias f)() { writefln(f("bar")); } bar!((str) { return str; })(); Is this a bug? -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/ $B%a%s%P!<Jg=8Cf(B http://tpf.techtalk.jp/
Apr 20 2009
bearophile wrote:tama:void foo(alias f)() { writefln(f(3, 4)); } foo!((x,y){ return x * y; })(); This code doesn't work(compile error).
To me the following works: import std.stdio: writeln; void foo(alias f)() { writeln(f(3, 4)); } void main() { foo!((x,y){ return x * y; })(); }
I tested following code. writefln(3 * 4); This code doesn't work in the first place:-< Sorry, it didn't matter. -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/ $B%a%s%P!<Jg=8Cf(B http://tpf.techtalk.jp/
Apr 20 2009
On Mon, 20 Apr 2009 14:58:38 +0400, tama <repeatedly gmail.com> wrote:bearophile wrote:tama:void foo(alias f)() { writefln(f(3, 4)); } foo!((x,y){ return x * y; })(); This code doesn't work(compile error).
To me the following works: import std.stdio: writeln; void foo(alias f)() { writeln(f(3, 4)); } void main() { foo!((x,y){ return x * y; })(); }
I tested following code. writefln(3 * 4); This code doesn't work in the first place:-< Sorry, it didn't matter.
writefln now expects a string as a first argument. Use writeln() if you need no formattings, it is both faster and safer.
Apr 20 2009
Denis Koroskin wrote:writefln now expects a string as a first argument. Use writeln() if you need no formattings, it is both faster and safer.
I checked D2 changelog and founded it at version 2.006 and 2.029. Thanks! -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/ $B%a%s%P!<Jg=8Cf(B http://tpf.techtalk.jp/
Apr 20 2009
Using D1 feels especially retarded today :(This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Apr 20 2009
Saaa wrote:Using D1 feels especially retarded today :(
Don't cry now. :-) Soon you'll be using D2 for work, and cry when you see the D3 change log...
Apr 20 2009
On Mon, Apr 20, 2009 at 2:47 PM, Saaa <empty needmail.com> wrote:Using D1 feels especially retarded today :(
Why retarded ?
Apr 20 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
The documentation for completeSort in std.algorithm says: Performs O(n * log(n)) (best case) to O(n * log(n)) (worst-case) evaluations of swap. I wonder what it should be.
Apr 20 2009
Georg Wrede wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
The documentation for completeSort in std.algorithm says: Performs O(n * log(n)) (best case) to O(n * log(n)) (worst-case) evaluations of swap. I wonder what it should be.
Sorry, what was I thinking? I think (without being sure) that the complexity of completeSort is O(rhs.length * log(t)) in the best case, and O(t * log(t)) in the worst case, where t = lhs.length + rhs.length. Andrei
Apr 20 2009
Andrei Alexandrescu wrote:Georg Wrede wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
The documentation for completeSort in std.algorithm says: Performs O(n * log(n)) (best case) to O(n * log(n)) (worst-case) evaluations of swap. I wonder what it should be.
Sorry, what was I thinking? I think (without being sure) that the complexity of completeSort is O(rhs.length * log(t)) in the best case, and O(t * log(t)) in the worst case, where t = lhs.length + rhs.length.
I revise that. Best case, there's temporary memory to allocate and then the complexity is that of sorting rhs plus merge lhs and rhs using extra memory. That is O(lhs.length + rhs.length * log(rhs.length)). Worst case, there's no temporary memory available so we need to sort the whole thing. That means O((lhs.length + rhs.length) * log(rhs.length + rhs.length)). I committed the fixed module. Andrei
Apr 20 2009
== Quote from Walter Bright (newshound1 digitalmars.com)'s articleThis is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Two small issues I've just run into that might warrant a quick update: Line 908 in random.d calls the deprecated rand_seed() for the old school random number generators from the static constructor. This means that std.random just plain can't be used out of the box. Also, when using std.string, I get the following linker errors on the Win32 build: Symbol Undefined _D3std6string6striprFAyaZAya Symbol Undefined _D3std6string6striplFAyaZAya
Apr 20 2009
== Quote from dsimcha (dsimcha yahoo.com)'s article== Quote from Walter Bright (newshound1 digitalmars.com)'s articleThis is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Line 908 in random.d calls the deprecated rand_seed() for the old school random number generators from the static constructor. This means that std.random just plain can't be used out of the box. Also, when using std.string, I get the following linker errors on the Win32 build: Symbol Undefined _D3std6string6striprFAyaZAya Symbol Undefined _D3std6string6striplFAyaZAya
Never mind on the linker error. That was caused by me forgetting to recompile parts of my code. The random thing looks legit, though.
Apr 20 2009
dsimcha wrote:== Quote from dsimcha (dsimcha yahoo.com)'s article== Quote from Walter Bright (newshound1 digitalmars.com)'s articleThis is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Line 908 in random.d calls the deprecated rand_seed() for the old school random number generators from the static constructor. This means that std.random just plain can't be used out of the box. Also, when using std.string, I get the following linker errors on the Win32 build: Symbol Undefined _D3std6string6striprFAyaZAya Symbol Undefined _D3std6string6striplFAyaZAya
Never mind on the linker error. That was caused by me forgetting to recompile parts of my code. The random thing looks legit, though.
Ok, I've undeprecated rand_seed, sigh. I was hoping I'd eliminate rand() entirely from this release, but Walter pointed out it would break too much code. So I left rand() and rand_seed() as deprecated. Now I only left rand() deprecated so at least the static constructor works. Andrei
Apr 20 2009
Andrei Alexandrescu wrote:Ok, I've undeprecated rand_seed, sigh. I was hoping I'd eliminate rand() entirely from this release, but Walter pointed out it would break too much code. So I left rand() and rand_seed() as deprecated. Now I only left rand() deprecated so at least the static constructor works.
I think the right fix for that is for the compiler to not complain about deprecated symbol usage if the usage is in the same module the deprecated symbol is defined in.
Apr 20 2009
Walter Bright wrote:Andrei Alexandrescu wrote:Ok, I've undeprecated rand_seed, sigh. I was hoping I'd eliminate rand() entirely from this release, but Walter pointed out it would break too much code. So I left rand() and rand_seed() as deprecated. Now I only left rand() deprecated so at least the static constructor works.
I think the right fix for that is for the compiler to not complain about deprecated symbol usage if the usage is in the same module the deprecated symbol is defined in.
Reading this, I thought "No chance Walter will ever do this" until I saw the poster's name :o). Andrei
Apr 20 2009
Andrei Alexandrescu wrote:Walter Bright wrote:I think the right fix for that is for the compiler to not complain about deprecated symbol usage if the usage is in the same module the deprecated symbol is defined in.
Reading this, I thought "No chance Walter will ever do this" until I saw the poster's name :o).
It is consistent with the ideas behind private access. Presumably the person working on the module knows what they're doing, no need to hide it from himself.
Apr 20 2009
I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
Apr 20 2009
Craig Black Wrote:I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
holy guacashit this works. import std.algorithm; import std.range; import std.stdio; void main() { string[] a = [ "shit", "poop" ]; string[] b = [ "dump", "shite" ]; sort!((a, b) { return a > b; })(chain(a, b)); writeln(a, " ", b); } i'll be shat on. couple shitty problems tho. auto don't work shit for a and b. complains about fixed size strings'n'shit. then writeln(chain(a, b)) shites ChainImpl!(immutable(char)[][],immutable(char)[][]) to stdout. tat's liable to scare da shit outta a beginner.
Apr 20 2009
superdan wrote:Craig Black Wrote:I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
holy guacashit this works. import std.algorithm; import std.range; import std.stdio; void main() { string[] a = [ "shit", "poop" ]; string[] b = [ "dump", "shite" ]; sort!((a, b) { return a > b; })(chain(a, b)); writeln(a, " ", b); } i'll be shat on. couple shitty problems tho. auto don't work shit for a and b. complains about fixed size strings'n'shit. then writeln(chain(a, b)) shites ChainImpl!(immutable(char)[][],immutable(char)[][]) to stdout. tat's liable to scare da shit outta a beginner.
Poop is funny! :)
Apr 20 2009
superdan wrote:Craig Black Wrote:I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
holy guacashit this works. import std.algorithm; import std.range; import std.stdio; void main() { string[] a = [ "shit", "poop" ]; string[] b = [ "dump", "shite" ]; sort!((a, b) { return a > b; })(chain(a, b)); writeln(a, " ", b); } i'll be shat on. couple shitty problems tho. auto don't work shit for a and b. complains about fixed size strings'n'shit. then writeln(chain(a, b)) shites ChainImpl!(immutable(char)[][],immutable(char)[][]) to stdout. tat's liable to scare da shit outta a beginner.
Thanks... I guess :o). Any chance you could submit the issues to bugzilla? I think the problem with string arrays is already known, but I need a memento to make writeln work with ranges. Andrei
Apr 20 2009
Craig Black wrote:I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
Thanks. Walter pointed out to me something interesting - STL is non-intuitive. That doesn't make it any less true (as a pursuit of the most generic incarnation of fundamental structs and algos). It's non-intuitive the same way complex numbers and relativity theory are non-intuitive. No language has ever managed to comprehend STL by sheer chance. (This in spite of e.g. C# adding a boatload of new features with each release.) There are two that can express it at all: C++ and D. Both C++ and D had to be changed to allow STL to exist, and became better languages as a result. The range shtick and D's support for lambdas is taking STL support to a whole new level. The downside is, it's rather difficult to explain the STL to anyone using other languages and wanting to just figure what the STL buzz is all about. Andrei
Apr 20 2009
Andrei Alexandrescu wrote:Craig Black wrote:I like very much the direction D2 is going now. Language refactoring and enhancements driven by the goal of more elegant implementation of standard libraries. This approach seems very practical and promising. Thank you very much and keep it up! -Craig
Thanks. Walter pointed out to me something interesting - STL is non-intuitive. That doesn't make it any less true (as a pursuit of the most generic incarnation of fundamental structs and algos). It's non-intuitive the same way complex numbers and relativity theory are non-intuitive. No language has ever managed to comprehend STL by sheer chance. (This in spite of e.g. C# adding a boatload of new features with each release.) There are two that can express it at all: C++ and D. Both C++ and D had to be changed to allow STL to exist, and became better languages as a result. The range shtick and D's support for lambdas is taking STL support to a whole new level. The downside is, it's rather difficult to explain the STL to anyone using other languages and wanting to just figure what the STL buzz is all about.
I wrote my MSc thesis about the STL. I think the conceptual idea was clean and clear, and at the time it was reasonably easy to explain it to even the professors. ;-) Today, however, and especially with the advanced implementation we have here in D, if someone has no prior knowledge of the STL way of thinking, it may be really hard to get them to 'get it'. There are too many trees up front to grasp the forest. What's sad, http://en.wikipedia.org/wiki/Standard_Template_Library really sucks at introducing the STL on a conceptual level. Even worse, that is actually the only thing it *should* do. Everyting else is optional.
Apr 20 2009
Georg Wrede, el 21 de abril a las 09:25 me escribiste:What's sad, http://en.wikipedia.org/wiki/Standard_Template_Library really sucks at introducing the STL on a conceptual level. Even worse, that is actually the only thing it *should* do. Everyting else is optional.
You should improve it then =) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------------
Apr 21 2009
Walter Bright wrote: In std.array, the example for back() is the same as for front(). The example for put() seems to be correct (and put() behaves accordingly), however, the asserted results are not what the reader would expect. If we are verbose enough to explain the dot notation here, then it would be prudent to elaborate a little as to the point of put(), and possibly the example (or the explanation) could include a use case.
Apr 20 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Was fwritefln() removed intentionally? Or should I write up a Bugzilla? I didn't noteice a mention in changelog.
Apr 19 2009
Russell Lewis wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Was fwritefln() removed intentionally? Or should I write up a Bugzilla? I didn't noteice a mention in changelog.
Sorry. It was removed intentionally along with all functions that manipulate FILE* directly. Its functional equivalent is File.writefln. If all you have is a handle, use File.wrapFile(fhandle).writefln. Andrei
Apr 20 2009
It's in dmd-v2.026/src/phobos/std/stdio.d:void fwritefln(FILE* fp, ...) but I cannot find it in 2.029.
Apr 20 2009
annoyed Wrote:It's in dmd-v2.026/src/phobos/std/stdio.d:void fwritefln(FILE* fp, ...) but I cannot find it in 2.029.
It was removed, use File.writefln() instead. std.stdio has been rewritten so you might want to take a look at the docs. Andrew
Apr 20 2009
Walter, how often do you update your working copy from the SVN? Obviously less than once every 2 releases. Stewart.
Apr 20 2009
Stewart Gordon wrote:Walter, how often do you update your working copy from the SVN? Obviously less than once every 2 releases.
As far as I know, it is current. Everything got checked in.
Apr 20 2009
Hello Walter,Stewart Gordon wrote:Walter, how often do you update your working copy from the SVN? Obviously less than once every 2 releases.
I think he was asking about the otherway (not that I known why)
Apr 20 2009
BCS wrote:I think he was asking about the otherway (not that I known why)
I think he'll need to be more specific!
Apr 20 2009
Well, there's push (svn commit) and pull (svn up), so he must mean one or the other... -[Unknown] Walter Bright wrote:BCS wrote:I think he was asking about the otherway (not that I known why)
I think he'll need to be more specific!
Apr 20 2009
Walter Bright wrote:Stewart Gordon wrote:Walter, how often do you update your working copy from the SVN? Obviously less than once every 2 releases.
As far as I know, it is current. Everything got checked in.
So how has the fix for http://d.puremagic.com/issues/show_bug.cgi?id=2580 (and probably others) not been included? Stewart.
Apr 21 2009
Stewart Gordon wrote:So how has the fix for http://d.puremagic.com/issues/show_bug.cgi?id=2580 (and probably others) not been included?
I'll look into it.
Apr 27 2009
Stewart Gordon wrote:Walter Bright wrote:Stewart Gordon wrote:Walter, how often do you update your working copy from the SVN? Obviously less than once every 2 releases.
As far as I know, it is current. Everything got checked in.
So how has the fix for http://d.puremagic.com/issues/show_bug.cgi?id=2580 (and probably others) not been included?
The code fix for this is in. You can see it in dmd/src/compiler/dmd/dmain2.d: rt_init(). I haven't updated the documentation yet though (this last release took me a bit by surprise)--I'll take care of that before the next release.
Apr 27 2009
On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Wicked awesome! file:///C:/dmd/html/d/phobos/std_range.html#cons Looks like bug 2676 was fixed in 2.027
Apr 20 2009
On Mon, 20 Apr 2009 09:57:55 +0200, Max Samukha <samukha voliacable.com.removethis> wrote:On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Wicked awesome! file:///C:/dmd/html/d/phobos/std_range.html#cons
Looks like bug 2676 was fixed in 2.027
Apr 21 2009
Max Samukha wrote:On Mon, 20 Apr 2009 09:57:55 +0200, Max Samukha <samukha voliacable.com.removethis> wrote:On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
file:///C:/dmd/html/d/phobos/std_range.html#cons
Looks like bug 2676 was fixed in 2.027
Thanks. I uncommented the unittest, updated the doc, and checked in. Andrei
Apr 21 2009
On Tue, 21 Apr 2009 07:42:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Max Samukha wrote:On Mon, 20 Apr 2009 09:57:55 +0200, Max Samukha <samukha voliacable.com.removethis> wrote:On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
file:///C:/dmd/html/d/phobos/std_range.html#cons
Looks like bug 2676 was fixed in 2.027
Thanks. I uncommented the unittest, updated the doc, and checked in. Andrei
A couple more minor doc issues: http://www.digitalmars.com/d/2.0/phobos/std_range.html: instances of "the popFront" need to be corrected to "the next". On the std.algorithm page, the examples for "map" and "filter" don't compile due to the fixed size array in equal(). The example for "bringToFront" is outdated. The comments for "remove": "If $(s =" -> "If $(D s ="
Apr 22 2009
On Wed, 22 Apr 2009 00:32:27 -0700, Brad Roberts <braddr puremagic.com> wrote:Max Samukha wrote:On Tue, 21 Apr 2009 07:42:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Max Samukha wrote:On Mon, 20 Apr 2009 09:57:55 +0200, Max Samukha <samukha voliacable.com.removethis> wrote:On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
file:///C:/dmd/html/d/phobos/std_range.html#cons
Looks like bug 2676 was fixed in 2.027
Andrei
A couple more minor doc issues: http://www.digitalmars.com/d/2.0/phobos/std_range.html: instances of "the popFront" need to be corrected to "the next". On the std.algorithm page, the examples for "map" and "filter" don't compile due to the fixed size array in equal(). The example for "bringToFront" is outdated. The comments for "remove": "If $(s =" -> "If $(D s ="
Please file a bug report. Posts here are are good way for issues to fall through the cracks. Thanks, Brad
done http://d.puremagic.com/issues/show_bug.cgi?id=2874
Apr 22 2009
Max Samukha wrote:On Tue, 21 Apr 2009 07:42:46 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Max Samukha wrote:On Mon, 20 Apr 2009 09:57:55 +0200, Max Samukha <samukha voliacable.com.removethis> wrote:On Mon, 20 Apr 2009 00:09:09 -0700, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
file:///C:/dmd/html/d/phobos/std_range.html#cons
Looks like bug 2676 was fixed in 2.027
Andrei
A couple more minor doc issues: http://www.digitalmars.com/d/2.0/phobos/std_range.html: instances of "the popFront" need to be corrected to "the next". On the std.algorithm page, the examples for "map" and "filter" don't compile due to the fixed size array in equal(). The example for "bringToFront" is outdated. The comments for "remove": "If $(s =" -> "If $(D s ="
Please file a bug report. Posts here are are good way for issues to fall through the cracks. Thanks, Brad
Apr 22 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
This is looking very nice! I want to switch from D1 to D2, but... I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work? I admit I don't know much about these things, and what I'm going to say next may not make sense at all, but here goes: x86-64 is just a superset of x86, right? Wouldn't it be possible, as a first step in the direction of a full-fledged x86-64 compiler, to simply make one that uses the same instruction set as the current DMD, but, I dunno, marks the executable as 64-bit (or something like that)? Specialisation and optimisation for the 64-bit architecture could then come at a later point in time. I know it is possible to run the 32-bit compiler (and the executables it produces) on a 64-bit operating system, but it isn't possible to link against 64-bit libraries. This means that one has to install and maintain 32-bit versions of all the libraries one wants to use, and those are, in general, not available through the repositories of most 64-bit distros. -Lars
Apr 21 2009
Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
This is looking very nice! I want to switch from D1 to D2, but... I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work? I admit I don't know much about these things, and what I'm going to say next may not make sense at all, but here goes: x86-64 is just a superset of x86, right? Wouldn't it be possible, as a first step in the direction of a full-fledged x86-64 compiler, to simply make one that uses the same instruction set as the current DMD, but, I dunno, marks the executable as 64-bit (or something like that)? Specialisation and optimisation for the 64-bit architecture could then come at a later point in time.
It's not quite that simple. It's not a full superset; some x86 instructions are not valid x86-64 instructions. For example, I think 'inc' was removed to make place for prefixes that set some flags for the next instruction and allow it to use the extra registers r8-r15.
Apr 21 2009
Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
This is looking very nice! I want to switch from D1 to D2, but... I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work? I admit I don't know much about these things, and what I'm going to say next may not make sense at all, but here goes: x86-64 is just a superset of x86, right? Wouldn't it be possible, as a first step in the direction of a full-fledged x86-64 compiler, to simply make one that uses the same instruction set as the current DMD, but, I dunno, marks the executable as 64-bit (or something like that)? Specialisation and optimisation for the 64-bit architecture could then come at a later point in time.
I'm pretty sure that 64-bit code is binary incompatible with 32-bit code. For example: struct Foo { void* ptr; } Is a different size for 32-bit and 64-bit code.I know it is possible to run the 32-bit compiler (and the executables it produces) on a 64-bit operating system, but it isn't possible to link against 64-bit libraries. This means that one has to install and maintain 32-bit versions of all the libraries one wants to use, and those are, in general, not available through the repositories of most 64-bit distros.
This is because the OS puts the CPU into a 32-bit compatible mode, but it can't magic away the differences between 32-bit and 64-bit code.-Lars
The best bet for 64-bit D executables at this point is probably LDC; dunno what the current state is, though. -- Daniel
Apr 21 2009
Daniel Keep wrote:Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
The best bet for 64-bit D executables at this point is probably LDC; dunno what the current state is, though.
The state for D2 is currently "very broken", AFAIK.
Apr 21 2009
Daniel Keep wrote: ...-Lars
The best bet for 64-bit D executables at this point is probably LDC; dunno what the current state is, though. -- Daniel
if you grep the dmd backend sources for x86_64, you'll get some results. Don't know what that means though, the source looks like magic to me!
Apr 21 2009
Lutger wrote:Daniel Keep wrote: ...-Lars
dunno what the current state is, though. -- Daniel
if you grep the dmd backend sources for x86_64, you'll get some results. Don't know what that means though, the source looks like magic to me!
code generation. Much more fun is: $ cd src/dmd $ grep "goto " * -R
Apr 21 2009
Don wrote:Lutger wrote:Daniel Keep wrote: ...-Lars
dunno what the current state is, though. -- Daniel
if you grep the dmd backend sources for x86_64, you'll get some results. Don't know what that means though, the source looks like magic to me!
code generation. Much more fun is: $ cd src/dmd $ grep "goto " * -R
you forgot " | less" there, what the hell...this code can't be human.
Apr 21 2009
Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Apr 21 2009
Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
Apr 21 2009
Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g> Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c". What the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
Apr 22 2009
Don wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g>
Yeah. But now I'm getting a bad conscience, this is beginning to look like Walter-bashing... :-)Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c". What the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
I guess Walter has to keep alternating between ASM, C and D. And a lot of ASM coding is nothing more than a bunch of MOV and JMP stuff. And file naming conventions here look like what one typically finds in development code (before some pre-publishing guy has tidyed it up with a lot of global search&replaces). And, after all, the C files never were meant to be public anyway. Actually, the one interesting question might be, would rewriting this code in a structured fashion (I mean, removing the gotos) make it slower? (Not that I'd be suggesting Walter should do it. Just an academic question.)
Apr 22 2009
Georg Wrede wrote:Don wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g>
Yeah. But now I'm getting a bad conscience, this is beginning to look like Walter-bashing... :-)
I think those code quality metrics are ridiculous. The prejudice against 'goto' is really just brainwashing and totally without basis. Here's a recent link from Andrew Koenig, who really should know better. http://dobbscodetalk.com/index.php?option=com_myblog&show=What-Dijkstra-said-was-harmful-about-goto-statements.html&Itemid=29 Can you see his fundamental mistake? He talks about "the program" (just as Dijkstra said), but it's just not relevant for C/C++/D/Pascal/... or any other structured programming language. Wherever he says "program" you should substitute "function". And then the force of the argument totally disappears. The problem with goto in an unstructured language is that when you see a label, you don't know where it came from. It could be anywhere in the entire program (maybe a million lines of code!) And that's a complete disaster. But in a structured language, you know it's from somewhere in the function. And this is no different from any other control structure. You ALWAYS have to look at the whole scope you're in. void foo(){ int n; bool b = true; while (b) { if (n==4) { /* when do we get here? You have to read the whole function to find out. Where does n get modified? */ } : : : } } Heck, even in inline ASM in D, you can't write the kind of spaghetti code Dijkstra was complaining about. You always have local scope. Yet, I personally have been so affected by anti-goto brainwashing that I've never used goto in C, C++, or D. But I gradually realised that it was just brainwashing. I've never experienced any problem with goto in ASM.Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c". What the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
I guess Walter has to keep alternating between ASM, C and D. And a lot of ASM coding is nothing more than a bunch of MOV and JMP stuff. And file naming conventions here look like what one typically finds in development code (before some pre-publishing guy has tidyed it up with a lot of global search&replaces). And, after all, the C files never were meant to be public anyway. Actually, the one interesting question might be, would rewriting this code in a structured fashion (I mean, removing the gotos) make it slower? (Not that I'd be suggesting Walter should do it. Just an academic question.)
I doubt it'd affect the speed at all. It'd probably make it longer. There are cases in DMD where it seems to make the control flow simpler.
Apr 22 2009
Don wrote:Georg Wrede wrote:Don wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g>
Yeah. But now I'm getting a bad conscience, this is beginning to look like Walter-bashing... :-)
I think those code quality metrics are ridiculous. The prejudice against 'goto' is really just brainwashing and totally without basis.
Well, at the time, they had no choice. Unstructured code was the norm, and people who tangled themselves in spaghetti never noticed it's because of goto usage. Instead they just preceived programming as hard. The language on my first computer was old fashioned BASIC, with line numbers and no named subroutines or structural elements. I felt that the effort needed to program was exponential to the number of lines. In hindsight, that must have been entirely because I'd had no higher education in programming, no notion of structuring the code (in any particular way), etc. But the absolutely worst thing was that one couldn't pass parameters to subroutines. (gosub <lineNumber>) And all variables were global. In those days most programming was done in COBOL, by (essentially) non-programmers. (The idea of COBOL was, after all, to be usable by business people, not MSc programmers.) Jackson had to change not only the methodology, but before that, the concept and the motivation for using structured programming. That was the hard part, and it needed some serious evangelising and brainwashing, to overcome the inertia. Unfortunately, that meant murdering, dismembering, and pulverizing any least hint of even thinking about using goto. And as with any paradigm shift, the disciples took it to religious extremes.Here's a recent link from Andrew Koenig, who really should know better. http://dobbscodetalk.com/index.php?option=com_myblog&show=What-Dijkstra-said-was-harmful-about-goto-state ents.html&Itemid=29 Can you see his fundamental mistake? He talks about "the program" (just as Dijkstra said), but it's just not relevant for C/C++/D/Pascal/... or any other structured programming language. Wherever he says "program" you should substitute "function". And then the force of the argument totally disappears.
Yes.The problem with goto in an unstructured language is that when you see a label, you don't know where it came from. It could be anywhere in the entire program (maybe a million lines of code!) And that's a complete disaster. But in a structured language, you know it's from somewhere in the function. And this is no different from any other control structure. You ALWAYS have to look at the whole scope you're in. void foo(){ int n; bool b = true; while (b) { if (n==4) { /* when do we get here? You have to read the whole function to find out. Where does n get modified? */ } : : : } } Heck, even in inline ASM in D, you can't write the kind of spaghetti code Dijkstra was complaining about. You always have local scope.
OTOH, getting the algorithm may become tedious even in small snippets. For example, here's Algorithm M, from /Fundamental Algorithms/, Knuth 1969, page 95: M1: int j=n; int k=n; int m=X[n]; M2: if(k==0) goto M6; M3: if(X[k] <= m) goto M5; M4: j=k; m=X[k]; M5: k--; goto M2; M6: ; That's three gotos for six lines. How long did it take to fully figure out what it's doing? Way longer than if it were written in structured D, anyway.Yet, I personally have been so affected by anti-goto brainwashing that I've never used goto in C, C++, or D. But I gradually realised that it was just brainwashing. I've never experienced any problem with goto in ASM.
Same here. Last time I used it was in Pascal, and boy, did I have a bad conscience. It felt like I was doing something Mom has forbidden.Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c". What the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
I guess Walter has to keep alternating between ASM, C and D. And a lot of ASM coding is nothing more than a bunch of MOV and JMP stuff. And file naming conventions here look like what one typically finds in development code (before some pre-publishing guy has tidyed it up with a lot of global search&replaces). And, after all, the C files never were meant to be public anyway. Actually, the one interesting question might be, would rewriting this code in a structured fashion (I mean, removing the gotos) make it slower? (Not that I'd be suggesting Walter should do it. Just an academic question.)
I doubt it'd affect the speed at all. It'd probably make it longer. There are cases in DMD where it seems to make the control flow simpler.
Simpler, yes. Then again, I'd hate to see folks actually start using goto in D!!!! If Walter uses it, it's different, he's qualified. :-) Oh, (for interested readers,) here's the above code in a test bench: import std.stdio; void main() { enum {DUMMY}; int[] X = [DUMMY,2,3,4,19,18,17,5,1,6]; int n = X.length-1; M1: int j=n; int k=n; int m=X[n]; M2: if(k==0) goto M6; M3: if(X[k] <= m) goto M5; M4: j=k; m=X[k]; M5: k--; goto M2; M6: ; writeln("max: ", m, " pos: ", j); } The dummy and length-1 are needed because, in the old days, especially text books had arrays 1-based. Also numbering things in general used to be 1-based, because "computing culture" hadn't spread to the general public yet. You didn't want to explain all over again the merits of zero based indexing every time you chalked up an example. The interesting part is, still today, this algorithm is essentially what the computer ends up doing, no matter how "structured" our source code was.
Apr 23 2009
Georg Wrede wrote:Don wrote:Georg Wrede wrote:Don wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g>
Yeah. But now I'm getting a bad conscience, this is beginning to look like Walter-bashing... :-)
I think those code quality metrics are ridiculous. The prejudice against 'goto' is really just brainwashing and totally without basis.
Well, at the time, they had no choice. Unstructured code was the norm, and people who tangled themselves in spaghetti never noticed it's because of goto usage. Instead they just preceived programming as hard. The language on my first computer was old fashioned BASIC, with line numbers and no named subroutines or structural elements. I felt that the effort needed to program was exponential to the number of lines. In hindsight, that must have been entirely because I'd had no higher education in programming, no notion of structuring the code (in any particular way), etc. But the absolutely worst thing was that one couldn't pass parameters to subroutines. (gosub <lineNumber>) And all variables were global. In those days most programming was done in COBOL, by (essentially) non-programmers. (The idea of COBOL was, after all, to be usable by business people, not MSc programmers.) Jackson had to change not only the methodology, but before that, the concept and the motivation for using structured programming. That was the hard part, and it needed some serious evangelising and brainwashing, to overcome the inertia. Unfortunately, that meant murdering, dismembering, and pulverizing any least hint of even thinking about using goto. And as with any paradigm shift, the disciples took it to religious extremes.Here's a recent link from Andrew Koenig, who really should know better. http://dobbscodetalk.com/index.php?option=com_myblog&show=What-Dijkstra-said-was-harmful-about-goto-state ents.html&Itemid=29 Can you see his fundamental mistake? He talks about "the program" (just as Dijkstra said), but it's just not relevant for C/C++/D/Pascal/... or any other structured programming language. Wherever he says "program" you should substitute "function". And then the force of the argument totally disappears.
Yes.The problem with goto in an unstructured language is that when you see a label, you don't know where it came from. It could be anywhere in the entire program (maybe a million lines of code!) And that's a complete disaster. But in a structured language, you know it's from somewhere in the function. And this is no different from any other control structure. You ALWAYS have to look at the whole scope you're in. void foo(){ int n; bool b = true; while (b) { if (n==4) { /* when do we get here? You have to read the whole function to find out. Where does n get modified? */ } : : : } } Heck, even in inline ASM in D, you can't write the kind of spaghetti code Dijkstra was complaining about. You always have local scope.
OTOH, getting the algorithm may become tedious even in small snippets. For example, here's Algorithm M, from /Fundamental Algorithms/, Knuth 1969, page 95: M1: int j=n; int k=n; int m=X[n]; M2: if(k==0) goto M6; M3: if(X[k] <= m) goto M5; M4: j=k; m=X[k]; M5: k--; goto M2; M6: ; That's three gotos for six lines. How long did it take to fully figure out what it's doing? Way longer than if it were written in structured D, anyway.Yet, I personally have been so affected by anti-goto brainwashing that I've never used goto in C, C++, or D. But I gradually realised that it was just brainwashing. I've never experienced any problem with goto in ASM.
Same here. Last time I used it was in Pascal, and boy, did I have a bad conscience. It felt like I was doing something Mom has forbidden.Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c". What the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
I guess Walter has to keep alternating between ASM, C and D. And a lot of ASM coding is nothing more than a bunch of MOV and JMP stuff. And file naming conventions here look like what one typically finds in development code (before some pre-publishing guy has tidyed it up with a lot of global search&replaces). And, after all, the C files never were meant to be public anyway. Actually, the one interesting question might be, would rewriting this code in a structured fashion (I mean, removing the gotos) make it slower? (Not that I'd be suggesting Walter should do it. Just an academic question.)
I doubt it'd affect the speed at all. It'd probably make it longer. There are cases in DMD where it seems to make the control flow simpler.
Simpler, yes. Then again, I'd hate to see folks actually start using goto in D!!!! If Walter uses it, it's different, he's qualified. :-) Oh, (for interested readers,) here's the above code in a test bench: import std.stdio; void main() { enum {DUMMY}; int[] X = [DUMMY,2,3,4,19,18,17,5,1,6]; int n = X.length-1; M1: int j=n; int k=n; int m=X[n]; M2: if(k==0) goto M6; M3: if(X[k] <= m) goto M5; M4: j=k; m=X[k]; M5: k--; goto M2; M6: ; writeln("max: ", m, " pos: ", j); } The dummy and length-1 are needed because, in the old days, especially text books had arrays 1-based. Also numbering things in general used to be 1-based, because "computing culture" hadn't spread to the general public yet. You didn't want to explain all over again the merits of zero based indexing every time you chalked up an example. The interesting part is, still today, this algorithm is essentially what the computer ends up doing, no matter how "structured" our source code was.
Even for it's time Basic was a bad language. Fortran was much better, and it existed before Basic was created. (Basic was created as a "simple version" of Fortran. The language was, but using it wasn't.) I still believe, however, that the go to statement should be avoided. Even in small routines. Because they may not stay small. (Doesn't mean you shouldn't ever use it. Sometimes it may actually simplify AND clarify the code. But very rarely. I've only found occasion to actually use it about four times since structured programming features were introduced in the various languages that I use. Generally it can be replaced by a labeled break or continue statement...and even those I've rarely needed since I altered my style to accommodate structures. The one context I used to use the goto in is now handled by exceptions. (Yes, one can argue that a labeled break or continue is effectively a goto, but it is very different in having much more local context. It's limited to a nest of loops rather than to a function.)
Apr 23 2009
Georg Wrede wrote:Actually, the one interesting question might be, would rewriting this code in a structured fashion (I mean, removing the gotos) make it slower? (Not that I'd be suggesting Walter should do it. Just an academic question.)
Yes. For better or worse, goto is sometimes the best way to write efficient code without any duplication.
Apr 22 2009
Georg Wrede wrote:Yeah. But now I'm getting a bad conscience, this is beginning to look like Walter-bashing... :-)
Don't worry, I'm immune to that. Back in 1984 or so during a code review at work, a colleague grepped for goto and presented a listing of all the gotos with the comment about what a piece of crap my code was. A lot of what I use goto for Andrei has demonstrated can be replaced with scope guards and his enforce template.
Apr 27 2009
Don, el 22 de abril a las 09:24 me escribiste:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
It'd be really funny to pass it through one of those "code quality" metrics, one of the ones with a ridiculously heavy penalty for using goto. I think it'd tell you that DMD source is almost the lowest-quality code on the planet. <g>
Try the Linux kernel. The difference is: a) Well, Linux is a kernel =) b) Gotos are not used gratuitously in the kernel code, they are used to handle error, which is almost the only right way to do it in C. For what I saw for the DMD code that's not true. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- 1950 we were 3 billion people on the earth, today we are 6 billion people
Apr 22 2009
Don wrote:Actually, looking through the DMD source it becomes obvious that goto is really not a problem at all. The lack of comments is much more of a problem. (Especially with files with names like "e2ir.c".
e2ir => Expression To Intermediate RepresentationWhat the heck is "fltables.c", "cdxxx.c", "elxxx.c" ?). Even so, it's mostly not that difficult to understand.
Those are generated by optabgen.exe.
Apr 27 2009
Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
I see I was being too obscure. See "Colossus, the Forbin Project" http://us.imdb.com/title/tt0064177/
Apr 27 2009
Walter Bright wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
I see I was being too obscure. See "Colossus, the Forbin Project" http://us.imdb.com/title/tt0064177/
To clarify: you are *not* 80 feet high and protector of Rhodes?
Apr 27 2009
Walter Bright wrote:Georg Wrede wrote:Walter Bright wrote:Lutger wrote:what the hell...this code can't be human.
I was replaced by Colossus years ago.
Michael A. Jackson wouldn't approve 1175 gotos in 113 files.
I see I was being too obscure. See "Colossus, the Forbin Project" http://us.imdb.com/title/tt0064177/
Heh, by an incredible coincidence, it aired here a couple of weeks ago. Maybe that's why I felt the reference too obvious to comment on. I liked the end. Not what I expected. And more thought provoking like this. It also gave some new depth about understanding the Terminator.
Apr 28 2009
Georg Wrede wrote:Walter Bright wrote:I see I was being too obscure. See "Colossus, the Forbin Project" http://us.imdb.com/title/tt0064177/
Heh, by an incredible coincidence, it aired here a couple of weeks ago. Maybe that's why I felt the reference too obvious to comment on.
I think it is an overlooked classic.
Apr 28 2009
Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
This is looking very nice! I want to switch from D1 to D2, but... I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work?
I would kill for a 64-bit Linux DMD. I think it could take a lot of ways of coding to a whole new level. Sean and I have also been discussing how to integrate memory-mapped files with the garbage collector. In a 64-bit environment this makes for an awesome programming model. Andrei
Apr 21 2009
Andrei Alexandrescu wrote:Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
This is looking very nice! I want to switch from D1 to D2, but... I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work?
I would kill for a 64-bit Linux DMD. [...]
Who does one have to kill to get a 64-bit compiler around here? :) But seriously, now that the language itself is stabilising, I would consider this a major priority for further development of DMD. 64 bits is the (immediate) future. -Lars
Apr 21 2009
Andrei Alexandrescu, el 21 de abril a las 07:38 me escribiste:Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work?
I would kill for a 64-bit Linux DMD. I think it could take a lot of ways of coding to a whole new level. Sean and I have also been discussing how to integrate memory-mapped files with the garbage collector. In a 64-bit environment this makes for an awesome programming model.
Can you elaborate on that? Thanks. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------------
Apr 21 2009
Leandro Lucarella wrote:Andrei Alexandrescu, el 21 de abril a las 07:38 me escribiste:Lars T. Kyllingstad wrote:Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
I don't want to sound greedy or anything, and I know others have asked for this before, but is making a 64-bit Linux version of DMD a lot of work?
coding to a whole new level. Sean and I have also been discussing how to integrate memory-mapped files with the garbage collector. In a 64-bit environment this makes for an awesome programming model.
Can you elaborate on that?
Not much time, but in short: Memory-mapped files are not a pure library thing, they are core because they manipulate the address space. So they are quite like memory allocation. Unmapping files by hand is as unsafe as calling delete. So memory mapped files must be integrated with the collector: you map a file by hand, and the garbage collector closes it when there are no more references to the memory mapped for the file. The programming model is pretty cool - in 32 bit I always need to mind the address space because it's so densely populated. In 64 bits I can map all of my data files in memory and let the paging system and the garbage collector take care of the rest. Andrei
Apr 21 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Thanks so much, looking good! The lambda template parameters: very cool.
Apr 21 2009
Walter Bright wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Missing from the changelog: From 2.208: 2804 Impure nested functions should be legal inside pure functions From 2.209: std.math: Intrinsics std.math.yl2x and yl2xp1 added. Improves performance of std.math.log() and similar functions (and they are now pure nothrow). (Yes, I know, not very exciting compared to Andrei's new Phobos <g>).
Apr 21 2009
Don:From 2.208: 2804 Impure nested functions should be legal inside pure functions
Very good. Now that little example works: import std.c.stdio: printf; import std.conv: to; pure int double_sqr(int x) { int y, z; void do_sqr() { y *= y; } y = x; do_sqr(); z += y; y = x; do_sqr(); z += y; return z; } void main(string[] args) { int x = args.length == 2 ? to!(int)(args[1]) : 10; int y = double_sqr(x) + double_sqr(x); printf("4 * x * x = %d\n", y); } The outout is correct: 4 * x * x = 400 "Cleaned up" ASM produced by DMD V.2.029, -O -release -inline: double_sqr: push EAX mov ECX,EAX mov [ESP],0 mov [ESP],ECX imul EAX,[ESP] mov EDX,EAX mov [ESP],EAX mov EAX,ECX mov [ESP],ECX imul EAX,[ESP] add EDX,EAX mov [ESP],EAX mov EAX,EDX pop ECX ret double_sqr.do_sqr: mov ECX,[EAX] imul ECX,[EAX] mov [EAX],ECX ret main: L0: sub ESP,014h cmp dword ptr 018h[ESP],2 jne L21 mov EDX,01Ch[ESP] mov EAX,018h[ESP] mov EAX,8[EDX] mov EDX,0Ch[EDX] push EDX push EAX call near ptr parseString jmp short L26 L21: mov EAX,0Ah L26: call near ptr double_sqr add EAX,EAX mov ECX,offset FLAT:_DATA push EAX push ECX call near ptr printf As you can see there's only one call to double_sqr in the main program, so the pure semantics is working here. You can also see do_sqr is inlined into double_sqr. But the asm code inside double_sqr looks very hairy and long, and double_sqr itself isn't inlined in the main. Bye, bearophile
Apr 21 2009
I have tried the following code:
import std.c.stdio: printf;
import std.conv: to;
nothrow pure int double_sqr(int x) { // line 4
int y, z;
nothrow void do_sqr() { y *= y; }
y = x;
do_sqr();
z += y;
y = x;
do_sqr();
z += y;
return z;
}
void main(string[] args) {
int x = args.length == 2 ? to!(int)(args[1]) : 10;
int y = double_sqr(x) + double_sqr(x);
printf("4 * x * x = %d\n", y);
}
The compiler spits the following error:
pure_impure_test.d(4): Error: function pure_impure_test.double_sqr 'double_sqr'
is nothrow yet may throw
but I don't understand why. What are the things inside it that can throw an
exception?
Bye,
bearophile
Apr 21 2009
I have also tested the semantics of nested function purity:
import std.c.stdio: printf;
import std.conv: to;
pure int double_sqr(int x) {
pure int sqr(int y) { return y * y; }
return sqr(x) + sqr(x);
}
void main(string[] args) {
int x = args.length == 2 ? to!(int)(args[1]) : 10;
int y = double_sqr(x) + double_sqr(x);
printf("4 * x * x = %d\n", y);
}
Compiled without inlining:
-O -release
double_sqr.sqr:
mov EAX,4[ESP]
imul EAX,EAX
ret 4
double_sqr:
L0: push EAX
push EAX
xor EAX,EAX
call near ptr double_sqr.sqr
push EAX
sub ESP,4
xor EAX,EAX
push dword ptr 8[ESP]
call near ptr double_sqr.sqr
add ESP,4
mov ECX,EAX
pop EAX
add EAX,ECX
pop ECX
ret
main:
L0: push EAX
cmp dword ptr 8[ESP],2
jne L1D
mov EDX,0Ch[ESP]
mov EAX,8[ESP]
push dword ptr 0Ch[EDX]
push dword ptr 8[EDX]
call near ptr to!(int)()
jmp short L22
L1D: mov EAX,0Ah
L22: call near ptr double_sqr
add EAX,EAX
mov ECX,offset FLAT:_DATA
push EAX
push ECX
call near ptr printf
There's one call to double_sqr but unfortunately two to double_sqr.sqr.
Bye,
bearophile
Apr 21 2009
bearophile wrote:I have also tested the semantics of nested function purity: import std.c.stdio: printf; import std.conv: to; pure int double_sqr(int x) { pure int sqr(int y) { return y * y; } return sqr(x) + sqr(x); } void main(string[] args) { int x = args.length == 2 ? to!(int)(args[1]) : 10; int y = double_sqr(x) + double_sqr(x); printf("4 * x * x = %d\n", y); } Compiled without inlining: -O -release double_sqr.sqr: mov EAX,4[ESP] imul EAX,EAX ret 4 double_sqr: L0: push EAX push EAX xor EAX,EAX call near ptr double_sqr.sqr push EAX sub ESP,4 xor EAX,EAX push dword ptr 8[ESP] call near ptr double_sqr.sqr add ESP,4 mov ECX,EAX pop EAX add EAX,ECX pop ECX ret main: L0: push EAX cmp dword ptr 8[ESP],2 jne L1D mov EDX,0Ch[ESP] mov EAX,8[ESP] push dword ptr 0Ch[EDX] push dword ptr 8[EDX] call near ptr to!(int)() jmp short L22 L1D: mov EAX,0Ah L22: call near ptr double_sqr add EAX,EAX mov ECX,offset FLAT:_DATA push EAX push ECX call near ptr printf There's one call to double_sqr but unfortunately two to double_sqr.sqr. Bye, bearophile
Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code. I'm not sure that nested pure member functions should be legal.
Apr 21 2009
Don wrote:bearophile wrote:I have also tested the semantics of nested function purity: import std.c.stdio: printf; import std.conv: to; pure int double_sqr(int x) { pure int sqr(int y) { return y * y; } return sqr(x) + sqr(x); } void main(string[] args) { int x = args.length == 2 ? to!(int)(args[1]) : 10; int y = double_sqr(x) + double_sqr(x); printf("4 * x * x = %d\n", y); } Compiled without inlining: -O -release double_sqr.sqr: mov EAX,4[ESP] imul EAX,EAX ret 4 double_sqr: L0: push EAX push EAX xor EAX,EAX call near ptr double_sqr.sqr push EAX sub ESP,4 xor EAX,EAX push dword ptr 8[ESP] call near ptr double_sqr.sqr add ESP,4 mov ECX,EAX pop EAX add EAX,ECX pop ECX ret main: L0: push EAX cmp dword ptr 8[ESP],2 jne L1D mov EDX,0Ch[ESP] mov EAX,8[ESP] push dword ptr 0Ch[EDX] push dword ptr 8[EDX] call near ptr to!(int)() jmp short L22 L1D: mov EAX,0Ah L22: call near ptr double_sqr add EAX,EAX mov ECX,offset FLAT:_DATA push EAX push ECX call near ptr printf There's one call to double_sqr but unfortunately two to double_sqr.sqr. Bye, bearophile
Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
The bug is bugzilla 2807.I'm not sure that nested pure member functions should be legal.
And it turns out that sqr() isn't actually pure, in the same way that it wasn't nothrow in your first example. The 'pure' marker is silently being ignored. If you put the 'pure' at the end, you get bug 2807. --
Apr 21 2009
Don:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; [...] I'm not sure that nested pure member functions should be legal.
It's not fully equivalent to moving it out of the function because once you pull it out you add a name to the outer namespace: nested functions are useful to keep namespaces tidy too. So I'd like to have nested pure functions too. pure int foo(int y) { return y + y; } // outer foo pure void bar(int x) { pure int foo(int y) { return y * y; } return foo(x) * .foo(x); } Thank you, bye, bearophile
Apr 21 2009
bearophile wrote:Don:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; [...] I'm not sure that nested pure member functions should be legal.
It's not fully equivalent to moving it out of the function because once you pull it out you add a name to the outer namespace: nested functions are useful to keep namespaces tidy too. So I'd like to have nested pure functions too. pure int foo(int y) { return y + y; } // outer foo pure void bar(int x) { pure int foo(int y) { return y * y; } return foo(x) * .foo(x); } Thank you, bye, bearophile
That's true, but it seems quite difficult to get right. A pure nested function can in theory access immutable members in the outer function -- but must not access the parameters of the outer function. If there are no immutable members in the outer function, the compiler would ideally convert it into an external pure function, so that it doesn't need a frame pointer to the outer function. But it would need error messages for any use of mutable outer function members. Etc. It seems quite a lot of work for something of very limited use. Making it into a external, private pure function is almost the same.
Apr 21 2009
Don wrote:bearophile wrote:Don:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; [...] I'm not sure that nested pure member functions should be legal.
It's not fully equivalent to moving it out of the function because once you pull it out you add a name to the outer namespace: nested functions are useful to keep namespaces tidy too. So I'd like to have nested pure functions too. pure int foo(int y) { return y + y; } // outer foo pure void bar(int x) { pure int foo(int y) { return y * y; } return foo(x) * .foo(x); } Thank you, bye, bearophile
That's true, but it seems quite difficult to get right. A pure nested function can in theory access immutable members in the outer function -- but must not access the parameters of the outer function. If there are no immutable members in the outer function, the compiler would ideally convert it into an external pure function, so that it doesn't need a frame pointer to the outer function. But it would need error messages for any use of mutable outer function members. Etc. It seems quite a lot of work for something of very limited use. Making it into a external, private pure function is almost the same.
it's only 5 lines long! It gives an error message if a nested pure function accesses a mutable variable from an outer scope.
Apr 22 2009
Don:Actually it's not so difficult. I've created a patch for bug 2807 -- it's only 5 lines long! It gives an error message if a nested pure function accesses a mutable variable from an outer scope.
Thank you very much Don, your work helps a lot. Every time I try a tiny program I find something I don't understand: import std.stdio: writeln; import std.math: sqrt; import std.conv: to; void main(string[] args) { double x = args.length == 2 ? to!(double)(args[1]) : 4.0; writeln(sqrt(x) + sqrt(x)); } I have also tried with std.math.sin with similar results: L0: enter 8,0 mov EAX,8[EBP] cmp EAX,2 jne L30 cmp EAX,1 ja L1B mov EAX,6 call near ptr _D6test7__arrayZ L1B: mov EDX,0Ch[EBP] mov EAX,8[EBP] mov EAX,8[EDX] mov EDX,0Ch[EDX] push EDX push EAX call near ptr _D3std4conv13__T2toTdTAyaZ2toFAyaZd jmp short L36 L30: fld qword ptr FLAT:_DATA[00h] L36: fstp qword ptr -8[EBP] fld qword ptr -8[EBP] fsin fld qword ptr -8[EBP] fsin faddp ST(1),ST sub ESP,0Ch fstp tbyte ptr [ESP] call near ptr _D3std5stdio14__T7writelnTeZ7writelnFeZv xor EAX,EAX leave ret Isn't sin(x)+sin(x) pure? Even if the compiler doesn't want to replace x+x with x*2 because x is a floating point, it can do: y = sin(x) y+y And that gives the same result even with FPs. Note: with SSE2 it's even possible to perform two sqrt(double) at the same time, so a compiler can implement sin(x)+sin(y) with a single instruction (SQRTSD) (plus eventually some register loading/unloading). Bye, bearophile
Apr 22 2009
bearophile:so a compiler can implement sin(x)+sin(y) with a single instruction (SQRTSD)
I meant sqrt(x)+sqrt(y), sorry.
Apr 22 2009
bearophile wrote:Don:Actually it's not so difficult. I've created a patch for bug 2807 -- it's only 5 lines long! It gives an error message if a nested pure function accesses a mutable variable from an outer scope.
Thank you very much Don, your work helps a lot. Every time I try a tiny program I find something I don't understand: import std.stdio: writeln; import std.math: sqrt; import std.conv: to; void main(string[] args) { double x = args.length == 2 ? to!(double)(args[1]) : 4.0; writeln(sqrt(x) + sqrt(x)); } I have also tried with std.math.sin with similar results: L0: enter 8,0 mov EAX,8[EBP] cmp EAX,2 jne L30 cmp EAX,1 ja L1B mov EAX,6 call near ptr _D6test7__arrayZ L1B: mov EDX,0Ch[EBP] mov EAX,8[EBP] mov EAX,8[EDX] mov EDX,0Ch[EDX] push EDX push EAX call near ptr _D3std4conv13__T2toTdTAyaZ2toFAyaZd jmp short L36 L30: fld qword ptr FLAT:_DATA[00h] L36: fstp qword ptr -8[EBP] fld qword ptr -8[EBP] fsin fld qword ptr -8[EBP] fsin faddp ST(1),ST sub ESP,0Ch fstp tbyte ptr [ESP] call near ptr _D3std5stdio14__T7writelnTeZ7writelnFeZv xor EAX,EAX leave ret Isn't sin(x)+sin(x) pure? Even if the compiler doesn't want to replace x+x with x*2 because x is a floating point, it can do: y = sin(x) y+y And that gives the same result even with FPs.
Yes. From further investigation, I've found that: (1) the optimisation of pure only happens for int returns, not for floating-point return types. It should convert purefunc(x)+purefunc(x) into 2*purefunc(x) if the return type of purefunc is int, float, or complex. (2) the back-end isn't smart enough to convert f*2 into f+f. It's difficult to work out where it's optimising the int return. I can see where it marks pure calls as subexpressions to be potentially eliminated: OTae(op) is true in gflow.c(660) if it's a pure call, false if it's an impure call. The problem may simply be that the backend doesn't do much common subexpression elimination of floating-point expressions. I really don't understand the backend. It's quite cryptic. Key acronyms are AE, CP and VBE. Then there's Bin, Bgen, Bkill, etc. AE *might* be Available Expression (but what does that mean?) CP might be Copy Propagation info I've found that VBE = "Very Busy Expression"! (what does that mean?) Fixing your problem is beyond me at present, I think.
Apr 23 2009
Don:I really don't understand the backend. It's quite cryptic. Key acronyms are AE, CP and VBE. Then there's Bin, Bgen, Bkill, etc. AE *might* be Available Expression (but what does that mean?) CP might be Copy Propagation info I've found that VBE = "Very Busy Expression"! (what does that mean?)
I suggest to add comments to the DMD source code every time a small mystery is revealed, to rename the files once a much better name is found, to improve and refactor the code every time it a good thing to do it. Every time you put your hand in the code you can improve the code locally and leave it better then before (this is the Scout principle in programming). Then such patches/changes can be slowly folded back into DMD and with time the sources will improve and will become more readable. Once they can be understood better, further changes become faster and simpler. Bye, bearophile
Apr 23 2009
bearophile wrote:Don:I really don't understand the backend. It's quite cryptic. Key acronyms are AE, CP and VBE. Then there's Bin, Bgen, Bkill, etc. AE *might* be Available Expression (but what does that mean?) CP might be Copy Propagation info I've found that VBE = "Very Busy Expression"! (what does that mean?)
I suggest to add comments to the DMD source code every time a small mystery is revealed, to rename the files once a much better name is found, to improve and refactor the code every time it a good thing to do it. Every time you put your hand in the code you can improve the code locally and leave it better then before (this is the Scout principle in programming). Then such patches/changes can be slowly folded back into DMD and with time the sources will improve and will become more readable. Once they can be understood better, further changes become faster and simpler.
I'd love to do that, but unfortunately it's not easy to get _any_ changes into DMD. Only Walter has write-access to it, and AFAIK he checks every line and enters it manually. Like Linus was famous for doing with the Linux kernel.Bye, bearophile
Apr 23 2009
Don wrote:bearophile wrote:
Isn't sin(x)+sin(x) pure? Even if the compiler doesn't want to replace x+x with x*2 because x is a floating point, it can do: y = sin(x) y+y And that gives the same result even with FPs.
Yes. From further investigation, I've found that: (1) the optimisation of pure only happens for int returns, not for floating-point return types. It should convert purefunc(x)+purefunc(x) into 2*purefunc(x) if the return type of purefunc is int, float, or complex. (2) the back-end isn't smart enough to convert f*2 into f+f.
I learnt a lot about the backend in the process, maybe I can fix (1) now.
Apr 25 2009
On 2009-04-21 11:18:39 -0400, Don <nospam nospam.com> said:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
What about immutable local variables? A pure function can access immutable globals, so it should be able to access immutable locals too. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 21 2009
Michel Fortin wrote:On 2009-04-21 11:18:39 -0400, Don <nospam nospam.com> said:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
What about immutable local variables? A pure function can access immutable globals, so it should be able to access immutable locals too.
If you treat the nested function's context pointer as a pointer to a struct matching the stack layout, then you can have pure nested functions -- they have exactly the same semantics as a pure struct member function. -- Daniel
Apr 21 2009
Daniel Keep wrote:Michel Fortin wrote:On 2009-04-21 11:18:39 -0400, Don <nospam nospam.com> said:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
immutable globals, so it should be able to access immutable locals too.
If you treat the nested function's context pointer as a pointer to a struct matching the stack layout, then you can have pure nested functions -- they have exactly the same semantics as a pure struct member function. -- Daniel
True, but that would mean that it'd be pretty useless. It's almost exactly the same as not marking it pure. pure foo(int x) { int y; pure int bar(int z) { return z*z; } int a= bar(2); y++; int b = bar(2); // has to recalculate bar(2), because y has changed. } --- The basic issue is that the situations where marking a nested function as 'pure' is a good idea, is extremely limited. Compared to making it an external pure private function, with any desired immutable members passed as parameters, it has these advantages and disadvantages. + inaccessable to other functions in the same module. + can access immutable members in the outer function, without passing them as parameters. - slower, since it needs a context pointer as well as a frame pointer. I think those benefits are pathetic.
Apr 22 2009
Steven Schveighoffer wrote:On Wed, 22 Apr 2009 03:12:04 -0400, Don <nospam nospam.com> wrote:Daniel Keep wrote:Michel Fortin wrote:On 2009-04-21 11:18:39 -0400, Don <nospam nospam.com> said:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
immutable globals, so it should be able to access immutable locals too.
struct matching the stack layout, then you can have pure nested functions -- they have exactly the same semantics as a pure struct member function. -- Daniel
True, but that would mean that it'd be pretty useless. It's almost exactly the same as not marking it pure. pure foo(int x) { int y; pure int bar(int z) { return z*z; } int a= bar(2); y++; int b = bar(2); // has to recalculate bar(2), because y has changed. } --- The basic issue is that the situations where marking a nested function as 'pure' is a good idea, is extremely limited. Compared to making it an external pure private function, with any desired immutable members passed as parameters, it has these advantages and disadvantages. + inaccessable to other functions in the same module. + can access immutable members in the outer function, without passing them as parameters. - slower, since it needs a context pointer as well as a frame pointer. I think those benefits are pathetic.
What about treating nested functions of pure functions like a logical grouping of statements within the function? That is, when you call a nested function inside a pure function, the call can't be optimized, but any calls the nested function makes (to a global pure function) can be optimized, and the nested function still provides the same guarantees (cannot access any globals, must only call other pure functions), however it can access and modify locals within the outer function.
That's exactly what my recent change (2804) did.I use nested functions a lot not as mini functions within a function but as simple ways to avoid duplicating code everywhere in my function. You probably couldn't allow taking a delegate of such a function either.
I've just submitted a patch (2695) which makes usage of function pointers and delegates safe within pure functions. Basically, you can take the delegate of a nested function, but you can't call it. You could return it, but I believe that's OK, because it should become a closure. I'm on a quest to make 'pure' usable in D <g>.
Apr 22 2009
On Thu, Apr 23, 2009 at 2:37 PM, Don <nospam nospam.com> wrote:bearophile wrote:Don:I really don't understand the backend. It's quite cryptic. Key acronyms are AE, CP and VBE. Then there's Bin, Bgen, Bkill, etc. AE *might* be Available Expression (but what does that mean?) CP might be Copy Propagation info I've found that VBE = "Very Busy Expression"! (what does that mean?)
I suggest to add comments to the DMD source code every time a small mystery is revealed, to rename the files once a much better name is found, to improve and refactor the code every time it a good thing to do it. Every time you put your hand in the code you can improve the code locally and leave it better then before (this is the Scout principle in programming). Then such patches/changes can be slowly folded back into DMD and with time the sources will improve and will become more readable. Once they can be understood better, further changes become faster and simpler.
I'd love to do that, but unfortunately it's not easy to get _any_ changes into DMD. Only Walter has write-access to it, and AFAIK he checks every line and enters it manually. Like Linus was famous for doing with the Linux kernel.
Glad to hear I'm not the only one with that impression...
Apr 23 2009
bearophile wrote:I have tried the following code: import std.c.stdio: printf; import std.conv: to; nothrow pure int double_sqr(int x) { // line 4 int y, z; nothrow void do_sqr() { y *= y; } y = x; do_sqr(); z += y; y = x; do_sqr(); z += y; return z; } void main(string[] args) { int x = args.length == 2 ? to!(int)(args[1]) : 10; int y = double_sqr(x) + double_sqr(x); printf("4 * x * x = %d\n", y); } The compiler spits the following error: pure_impure_test.d(4): Error: function pure_impure_test.double_sqr 'double_sqr' is nothrow yet may throw but I don't understand why. What are the things inside it that can throw an exception? Bye, bearophile
Obviously my 2808 patch only solved one part of the problem. It compiles if you change do_sqr to void do_sqr() nothrow { y *= y; } Please add a bug report to Bugzilla.
Apr 21 2009
On Tue, Apr 21, 2009 at 8:56 PM, Don <nospam nospam.com> wrote:bearophile wrote:Don:Yes. Actually, marking a nested function as pure doesn't make much sens=
It's entirely equivalent to moving it outside the function; [...] I'm not sure that nested pure member functions should be legal.
It's not fully equivalent to moving it out of the function because once you pull it out you add a name to the outer namespace: nested functions =
useful to keep namespaces tidy too. So I'd like to have nested pure functions too. pure int foo(int y) { return y + y; } // outer foo pure void bar(int x) { =C2=A0pure int foo(int y) { return y * y; } =C2=A0return foo(x) * .foo(x); } Thank you, bye, bearophile
That's true, but it seems quite difficult to get right. A pure nested function can in theory access immutable members in the outer function -- =
must not access the parameters of the outer function. If there are no immutable members in the outer function, the compiler wou=
ideally convert it into an external pure function, so that it doesn't need a frame pointer to the outer function. But it would need err=
messages for any use of mutable outer function members. Etc. It seems quite a lot of work for something of very limited use. Making it into a external, private pure function is almost the same.
why not just make it a static pure nested function? or is that no longer proper D2 ?
Apr 21 2009
On Wed, 22 Apr 2009 03:12:04 -0400, Don <nospam nospam.com> wrote:Daniel Keep wrote:Michel Fortin wrote:On 2009-04-21 11:18:39 -0400, Don <nospam nospam.com> said:Yes. Actually, marking a nested function as pure doesn't make much sense. It's entirely equivalent to moving it outside the function; a nested pure function shouldn't be able to access any members of the enclosing function, otherwise it's not pure. But DMD doesn't enforce that, and so it creates inefficient and possibly buggy code.
immutable globals, so it should be able to access immutable locals too.
struct matching the stack layout, then you can have pure nested functions -- they have exactly the same semantics as a pure struct member function. -- Daniel
True, but that would mean that it'd be pretty useless. It's almost exactly the same as not marking it pure. pure foo(int x) { int y; pure int bar(int z) { return z*z; } int a= bar(2); y++; int b = bar(2); // has to recalculate bar(2), because y has changed. } --- The basic issue is that the situations where marking a nested function as 'pure' is a good idea, is extremely limited. Compared to making it an external pure private function, with any desired immutable members passed as parameters, it has these advantages and disadvantages. + inaccessable to other functions in the same module. + can access immutable members in the outer function, without passing them as parameters. - slower, since it needs a context pointer as well as a frame pointer. I think those benefits are pathetic.
What about treating nested functions of pure functions like a logical grouping of statements within the function? That is, when you call a nested function inside a pure function, the call can't be optimized, but any calls the nested function makes (to a global pure function) can be optimized, and the nested function still provides the same guarantees (cannot access any globals, must only call other pure functions), however it can access and modify locals within the outer function. I use nested functions a lot not as mini functions within a function but as simple ways to avoid duplicating code everywhere in my function. You probably couldn't allow taking a delegate of such a function either. -Steve
Apr 22 2009
On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("(J\(BnCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug? -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/ $B%a%s%P!<Jg=8Cf(B http://tpf.techtalk.jp/
Apr 21 2009
tama wrote:On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("\nCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug?
If you initialize the Mersenne twister with no seed it will start with seed 5489u. Andrei
Apr 22 2009
Steven Schveighoffer wrote:On Wed, 22 Apr 2009 13:49:18 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:tama wrote:On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("\nCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug?
If you initialize the Mersenne twister with no seed it will start with seed 5489u.
I think his point is in the second part of Case2, he skipped one element, but it appears that it didn't skip anything.
Oh ok, thanks tama and Steve. I know where the problem is (on the Mersenne twister, if you call popFront without ever calling head there's a bug). Could you submit a bug? I'm on battery and on short time, and Walter is bugging me :o). Andrei
Apr 22 2009
Masahiro Nakagawa wrote:I submitted this problem to bugzilla. http://d.puremagic.com/issues/show_bug.cgi?id=2882
Thanks! I fixed it and checked in std.random. Andrei
Apr 23 2009
On Wed, 22 Apr 2009 13:49:18 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:tama wrote:On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("\nCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug?
If you initialize the Mersenne twister with no seed it will start with seed 5489u.
I think his point is in the second part of Case2, he skipped one element, but it appears that it didn't skip anything. -Steve
Apr 22 2009
Changed sender name from screen name to real name. On Thu, 23 Apr 2009 02:55:37 +0900, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Wed, 22 Apr 2009 13:49:18 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:tama wrote:On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("\nCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug?
If you initialize the Mersenne twister with no seed it will start with seed 5489u.
I think his point is in the second part of Case2, he skipped one element, but it appears that it didn't skip anything.
Lack of talk about this problem:| -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/
Apr 22 2009
On Thu, 23 Apr 2009 03:12:16 +0900, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote:On Wed, 22 Apr 2009 13:49:18 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:tama wrote:On Mon, 20 Apr 2009 16:09:09 +0900, Walter Bright <newshound1 digitalmars.com> wrote:This is a major revision to Phobos, including Andrei's revolutionary new range support. http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.029.zip
Range is so cool! Though... I tried following code: void main() { writeln("Case1"); { Mt19937 gen = Mt19937(0); writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen = Mt19937(0); advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("\nCase2"); { Mt19937 gen; writeln(gen.front); gen.popFront; writeln(gen.front); } writeln("---"); { Mt19937 gen; advance(gen, 1); // skip 1 element writeln(gen.front); gen.popFront; writeln(gen.front); } } Result: Case1 2357136044 (1) 2546248239 (2) --- 2546248239 (2) 3071714933 (3) Case2 581869302 (1) 3890346734 (2) --- 581869302 (1)? 3890346734 (2)? I think 'Case1' is correct, but 'Case2' is wrong. Mt19937's bug?
If you initialize the Mersenne twister with no seed it will start with seed 5489u.
element, but it appears that it didn't skip anything.
Oh ok, thanks tama and Steve. I know where the problem is (on the Mersenne twister, if you call popFront without ever calling head there's a bug). Could you submit a bug? I'm on battery and on short time, and Walter is bugging me :o).
http://d.puremagic.com/issues/show_bug.cgi?id=2882 -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/
Apr 22 2009
On Thu, 23 Apr 2009 18:09:06 +0900, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Masahiro Nakagawa wrote:I submitted this problem to bugzilla. http://d.puremagic.com/issues/show_bug.cgi?id=2882
Thanks! I fixed it and checked in std.random.
std.random in svn works fine. Thanks for your quick response. -- tama <repeatedly gmail.com> http://profile.livedoor.com/repeatedly/
Apr 23 2009









"Simen Kjaeraas" <simen.kjaras gmail.com> 