|
Archives
D Programming
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
D.gnu
D
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
electronics
|
digitalmars.D - From Reddit
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
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:
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)
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
-----
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
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.
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.
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
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
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.
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
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
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
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
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
|
|