www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - From Reddit

reply bearophile <bearophileHUGS lycos.com> writes:
I have written some comments about the article written by Andrei Alexandrescu:

http://www.reddit.com/r/programming/comments/8t7s1/the_case_for_d_the_other_side_of_the_coin/

Andrei has commented some things on Reddit, I think it's better to move the
discussion here.

If there are wrong things in what I have written I'll fix them (Fixing a
LiveJournal post is simple, probably simpler than fixing an article on DDJ).


I have seldom been this annoyed at a piece of feedback, and I've received my
share of bile.<
I didn't mean to hurt feelings so much. I never had somethign against you or against D.
I have no idea what the author wants to convey.<
I have answered that in the first few lines:
Giving false expectations in possible new D users is dangerous. I think that
giving a more balanced account of the current situation is better, even if in
future most of current D problems may be fixed.<
I think your article shows mostly positive sides of D, even if what you say may become true in future. I think my comments (once fixed) are actually good for the spreading of D :-)
The article originates in some feedback that the author (I'd sent him a draft
for review) sent me, and that I considered unfit to integrate in the final
version.<
The article doesn't originate from that, it originates just from the final article you have written on DDJ.
Some comments are patently false (such as the one that you must compile with
dmc to call C functions on Windows).<
Is this true? I have seen many times people here answer that code has to be compiled with DMC, etc. If I am wrong I'll fix the text.
Some are ignorant (the author concluded that dmd can't optimize tail recursion
by trying it with the non-tail-recursive factorial function; and I took the
time to explain him!).<
If I compile this D2 program with DMD: import std.stdio: printf; import std.conv: to; int sum(int[] a, int start=0) { if (start >= a.length) return 0; else { return a[start] + sum(a, start+1); //auto b = a[start]; //return b + sum(a, start+1); } } void main(char[][] args) { int n = args.length > 1 ? to!int(args[1]) : 1; auto a = new int[n]; foreach(i, ref x; a) x = i; printf("%d\n", sum(a)); } This is the cleaned up code I obtain: sum: L0: push EAX push EAX push EBX cmp EAX,010h[ESP] jb L12 pop EBX add ESP,8 xor EAX,EAX ret 8 L12: mov EDX,014h[ESP] mov EBX,010h[ESP] mov EAX,[EAX*4][EDX] push EAX sub ESP,4 mov EAX,010h[ESP] push EDX inc EAX push EBX call near ptr _D4test3sumFAiiZi add ESP,4 mov ECX,EAX pop EAX add EAX,ECX pop EBX add ESP,8 ret 8 main L0: sub ESP,024h push EBX push ESI cmp dword ptr 030h[ESP],1 jbe L23 mov EDX,034h[ESP] mov EAX,030h[ESP] mov EAX,8[EDX] mov EDX,0Ch[EDX] push EDX push EAX call near ptr _D3std4conv19__T11parseStringTiZ11parseStringFAxaZi jmp short L28 L23: mov EAX,1 L28: mov ECX,offset FLAT:_D11TypeInfo_Ai6__initZ push EAX push ECX call near ptr __d_newarrayT xor EBX,EBX mov ESI,EDX mov 014h[ESP],EAX mov 018h[ESP],EDX add ESP,8 cmp 0Ch[ESP],EBX je L53 L49: mov [EBX*4][ESI],EBX inc EBX cmp EBX,0Ch[ESP] jb L49 L53: push dword ptr 010h[ESP] xor EAX,EAX push dword ptr 010h[ESP] call near ptr _D4test3sumFAiiZi mov EBX,offset FLAT:_DATA push EAX push EBX call near ptr _printf add ESP,8 xor EAX,EAX pop ESI pop EBX add ESP,024h ret LDC is almost able to turn that tail-call into a loop (you have to split the final expression in two parts, I don't know if in the meantime such limit has being lifed), and GCC is able to.
Some are just nitpicky beyond belief.<
I don't agree. Other anonymous people have answered lot of things in the comments in LiveJournal itself, in some time I'll fix things that have to be fixed, etc. Bye, bearophile
Jun 17 2009
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
bearophile wrote:
 Some comments are patently false (such as the one that you must compile with
dmc to call C functions on Windows).<
Is this true? I have seen many times people here answer that code has to be compiled with DMC, etc. If I am wrong I'll fix the text.
I thought this was pretty much true for DMD-compiled code, unless either function is in a DLL or some kind of object file converter is used. (Or an ancient non-DMC C compiler that still produces OMF, I suppose) Those are a lot of conditions, of course :P.
 Some are ignorant (the author concluded that dmd can't optimize tail recursion
by trying it with the non-tail-recursive factorial function; and I took the
time to explain him!).<
If I compile this D2 program with DMD: import std.stdio: printf; import std.conv: to; int sum(int[] a, int start=0) { if (start >= a.length) return 0; else { return a[start] + sum(a, start+1); //auto b = a[start]; //return b + sum(a, start+1); } } void main(char[][] args) { int n = args.length > 1 ? to!int(args[1]) : 1; auto a = new int[n]; foreach(i, ref x; a) x = i; printf("%d\n", sum(a)); } This is the cleaned up code I obtain:
[snip code with recursive call instead of loop]
 
 
 LDC is almost able to turn that tail-call into a loop (you have to split the
final expression in two parts, I don't know if in the meantime such limit has
being lifed), and GCC is able to.
He's right though; the code isn't properly tail recursive (it performs an add after the recursion). However, it can be *made* tail recursive by introducing an accumulator, which is something LLVM does here[1]. [1]: It currently does not realize the array load can be done before the function call, but I submitted a patch to LLVM for that. (This is why it currently needs to be split up, so that LDC emits the load before the function call)
Jun 17 2009
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Frits van Bommel wrote:
 bearophile wrote:
 Some are ignorant (the author concluded that dmd can't optimize tail 
 recursion by trying it with the non-tail-recursive factorial 
 function; and I took the time to explain him!).<
If I compile this D2 program with DMD: import std.stdio: printf; import std.conv: to; int sum(int[] a, int start=0) { if (start >= a.length) return 0; else { return a[start] + sum(a, start+1); //auto b = a[start]; //return b + sum(a, start+1); } } void main(char[][] args) { int n = args.length > 1 ? to!int(args[1]) : 1; auto a = new int[n]; foreach(i, ref x; a) x = i; printf("%d\n", sum(a)); }
He's right though; the code isn't properly tail recursive (it performs an add after the recursion). However, it can be *made* tail recursive by introducing an accumulator, which is something LLVM does here[1].
Note that if the accumulator is introduced manually, the tail recursion indeed gets eliminated by DMD (and turned into a loop). Code: (D1, Phobos or Tango) ----- extern(C) int printf(char*, ...); version(Tango) import tango.text.convert.Integer; else import std.conv; int sum(int[] a, int start=0, int acc = 0) { if (start >= a.length) return acc; else { return sum(a, start+1, acc + a[start]); //auto b = a[start]; //return b + sum(a, start+1); } } void main(char[][] args) { int n = args.length > 1 ? toInt(args[1]) : 1; auto a = new int[n]; foreach(i, ref x; a) x = i; printf("%d\n", sum(a)); } ----- With dmd -O -release, I get the following objdump output (demangled): ----- 08049b54 <int test.sum(int[], int, int)>: 8049b54: 55 push %ebp 8049b55: 8b ec mov %esp,%ebp 8049b57: 83 ec 10 sub $0x10,%esp 8049b5a: 53 push %ebx 8049b5b: 8b 5d 08 mov 0x8(%ebp),%ebx 8049b5e: 89 c1 mov %eax,%ecx 8049b60: 56 push %esi 8049b61: 57 push %edi 8049b62: 3b 5d 0c cmp 0xc(%ebp),%ebx 8049b65: 72 0b jb 8049b72 <int test.sum(int[], int, int)+0x1e> 8049b67: 5f pop %edi 8049b68: 8b c1 mov %ecx,%eax 8049b6a: 5e pop %esi 8049b6b: 5b pop %ebx 8049b6c: 8b e5 mov %ebp,%esp 8049b6e: 5d pop %ebp 8049b6f: c2 0c 00 ret $0xc 8049b72: 89 5d 08 mov %ebx,0x8(%ebp) 8049b75: 8b 55 10 mov 0x10(%ebp),%edx 8049b78: 8b 5d 0c mov 0xc(%ebp),%ebx 8049b7b: 89 d7 mov %edx,%edi 8049b7d: 8b 5d 08 mov 0x8(%ebp),%ebx 8049b80: 8b 34 9f mov (%edi,%ebx,4),%esi 8049b83: 03 f1 add %ecx,%esi 8049b85: 8d 53 01 lea 0x1(%ebx),%edx 8049b88: 3b 55 0c cmp 0xc(%ebp),%edx 8049b8b: 89 f1 mov %esi,%ecx 8049b8d: 89 d3 mov %edx,%ebx 8049b8f: 73 d6 jae 8049b67 <int test.sum(int[], int, int)+0x13> 8049b91: eb ed jmp 8049b80 <int test.sum(int[], int, int)+0x2c> 8049b93: 90 nop -----
Jun 17 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Frits van Bommel:

[LDC] [1]: It currently does not realize the array load can be done before the
function call, but I submitted a patch to LLVM for that. (This is why it
currently needs to be split up, so that LDC emits the load before the function
call)<
I guess you mean this: http://llvm.org/bugs/show_bug.cgi?id=4323 It seems they are accepting such changes of yours, you are good :-)
Note that if the accumulator is introduced manually, the tail recursion indeed
gets eliminated by DMD (and turned into a loop).<
Very good, thank you for modifying the code. I have done a similar error two times... I'll change the LiveJournal post ASAP. Bye and thank you, bearophile
Jun 17 2009
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
bearophile wrote:
 Frits van Bommel:
 
 [LDC] [1]: It currently does not realize the array load can be done before the
function call, but I submitted a patch to LLVM for that. (This is why it
currently needs to be split up, so that LDC emits the load before the function
call)<
I guess you mean this: http://llvm.org/bugs/show_bug.cgi?id=4323
Yes, but the mailing list post in the last comment has the latest version of the patch attached. (removing a prerequisite change that has already been applied, and fixing one of the tests which was too imprecise)
 It seems they are accepting such changes of yours, you are good :-)
Getting patches in isn't all that hard as long as they're not buggy and change something for the better :). Keeping them small helps too, since it makes for easier (and quicker) reviews.
 Note that if the accumulator is introduced manually, the tail recursion indeed
gets eliminated by DMD (and turned into a loop).<
Very good, thank you for modifying the code.
No problem.
Jun 17 2009
prev sibling parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 I have written some comments about the article written by Andrei Alexandrescu:
 
 http://www.reddit.com/r/programming/comments/8t7s1/the_case_for_d_the_other_side_of_the_coin/
 
 Andrei has commented some things on Reddit, I think it's better to move the
discussion here.
 Some comments are patently false (such as the one that you must compile with
dmc to call C functions on Windows).<
Is this true? I have seen many times people here answer that code has to be compiled with DMC, etc. If I am wrong I'll fix the text.
Using C code from DMD on Windows is exactly the same as using it from any Windows C++ compiler (or even a C compiler from a different vendor!). The statement should be removed. "Giving false expectations in possible new D users is dangerous." "A good article must...not just talk about good implementations that may be found years from now." I agree with this. But your list doesn't help. I don't think there's anything in your list which new users need to know.
Jun 25 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:
 Using C code from DMD on Windows is exactly the same as using it from 
 any Windows C++ compiler (or even a C compiler from a different 
 vendor!). 
I don't understand your words. Do you mean on Windows you can produce object code with MinGW too (just released 4.4!), and then use it from DMD D? Bye, bearophile
Jun 25 2009
parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 Don:
 Using C code from DMD on Windows is exactly the same as using it from 
 any Windows C++ compiler (or even a C compiler from a different 
 vendor!). 
I don't understand your words. Do you mean on Windows you can produce object code with MinGW too (just released 4.4!), and then use it from DMD D? Bye, bearophile
No. But that's nothing to do with D. This is an object file incompatibility, not a language issue. You can't use a MingW object file from DMC, or from MSVC, either. DMD can however use an object file from any C compiler which uses OMF object files, such as Watcom or DMC. OTOH you can get a MinGW object file, run it through an obj conversion utility, and then link it to DMD.
Jun 30 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:
 No. But that's nothing to do with D. This is an object file 
 incompatibility, not a language issue.
 You can't use a MingW object file from DMC, or from MSVC, either.
 DMD can however use an object file from any C compiler which uses OMF 
 object files, such as Watcom or DMC.
 OTOH you can get a MinGW object file, run it through an obj conversion 
 utility, and then link it to DMD.
I understand now, thank you for explaining me. I'll add such information to that part of the blog post. (I also have a lot of comments to answer there still, they are all anonymous). Bye, bearophile
Jun 30 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Don:
 No. But that's nothing to do with D. This is an object file 
 incompatibility, not a language issue.
 You can't use a MingW object file from DMC, or from MSVC, either.
 DMD can however use an object file from any C compiler which uses OMF 
 object files, such as Watcom or DMC.
 OTOH you can get a MinGW object file, run it through an obj conversion 
 utility, and then link it to DMD.
I understand now, thank you for explaining me. I'll add such information to that part of the blog post. (I also have a lot of comments to answer there still, they are all anonymous).
IMHO you should pull that post. It is at best appallingly thoughtless. Andrei
Jun 30 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 IMHO you should pull that post. It is at best appallingly thoughtless.
It has received 14 more long answers, I can't remove it (and I don't want too, because I thin it's interesting). Just for the record, that post of mine was never meant to offend you, despite it has. Bye, bearophile
Jun 30 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Andrei Alexandrescu:
 IMHO you should pull that post. It is at best appallingly thoughtless.
It has received 14 more long answers, I can't remove it (and I don't want too, because I thin it's interesting). Just for the record, that post of mine was never meant to offend you, despite it has.
Technically the post is drivel, but even that's besides the point. The problem is that it harms D by sowing and showing disunity within the community. Definitely it is not helping at all in the way you claimed. I am willing to believe this was a thoughtless attempt to do something good, instead a self-serving and attention-seeking piece, as it looks at the first sight. My article was promotional. It said so as early as the TITLE. "The Case for D". It was not "The State of D", "A Review of D", "A Discussion About D", or "A Round Table about D". If my purpose was to give an account of where D is at this moment, and if I somehow ended up giving an overly favorable view, then your piece (or better said a technically correct piece on the same subject) would have been entirely justified. As it stands, it is simply in bad taste, not to mention it reeks of mistakes and nitpicky, inconsequential points to boot (and I'm pleasantly surprised that reddit readers saw that). Andrei
Jun 30 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 The problem is that it harms D by sowing and showing disunity within the 
 community. Definitely it is not helping at all in the way you claimed.
Even languages with 15 years of development are filled with mistakes and tons of problems (so much that Bjarne Stroustrup wisely says: "There are just two kinds of languages: the ones everybody complains about and the ones nobody uses."). So all smart technical readers get suspicious when they read a text that shows mostly good sides. I believe such suspects are a risk worse than the risk of showing "disunity within the community".
 I am willing to believe this was a thoughtless attempt to do something 
 good, instead a self-serving and attention-seeking piece, as it looks at 
 the first sight.
Thank you. Nearly always I try to avoid the limelight. This time it may a bit different, but advertising my blog was not my main purpose. I may even ask you again to remove the link to my site from Phobos2 documentation, to avoid possible future troubles. You have written all the code, I don't want recognition: having a good Phobos2 is more than enough for me :-) bearophile
Jun 30 2009