www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Andy Glew reviews "The Case For D"

reply Walter Bright <newshound1 digitalmars.com> writes:
http://www.reddit.com/r/programming/comments/92ajk/andy_glew_reviews_the_case_for_the_d_programming/
Jul 17 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
http://www.reddit.com/r/programming/comments/92ajk/andy_glew_reviews_the_case_for_the_d_programming/

Everything is initialized (unless the programmer says not to, by saying "int x
= void").<

In LDC global static arrays are initialized to 0 if their content is set to =void. I sometimes have global static arrays of floats/doubles in small numeric D programs, the result is that the binary gets huge (those arrays are statically filled with NaNs that are present in the binary), this is not nice (a solution is to put =void, but even if LDC zeroes them anyway, I have situations where the resulting code is slow).
Signaling NaNs now play in D the role they were originally created for -- to
make the use of uninitialized floating-point variables trivial to track down.
They eradicate the nightmares you get in floating-point code when code fails
intermittently.<

Are the functions enableExceptions() / disableExceptions() shown us by Don in Phobos2? I have not found them there. If they are absent then they must be added to Phobos2. I'd also like a compiler switch that essentially calls enableExceptions() at the beginning of _Dmain. void enableExceptions() { version(D_InlineAsm_X86) { short cont; asm { fclex; fstcw cont; mov AX, cont; and AX, 0xFFFE; // enable invalid exception mov cont, AX; fldcw cont; } } } void disableExceptions() { version(D_InlineAsm_X86) { short cont; asm { fclex; fstcw cont; mov AX, cont; or AX, 0x1; // disable invalid exception mov cont, AX; fldcw cont; } } }
The instant recognition of how useful this can be indicates a high level of
awareness of numerics in the D community.<

Surely the numerics awareness in the D community is higher than other language communities I have found, but it's not enough yet: here I don't see enough people asking for the loop/matrix/parallel tricks done by modern Fortran/ Chapel/ Fortress/ etc.
OK, so FP are initialized to signalling NaNs. This is good. Although maybe not
so good for computer architectures that have deprecated NaN support.<

I think DMD is mostly designed for X86.
Initializing integer types to 0 is better than nothing. But even this can give
errors. Initializing to something that signals wiould be nice. Buit there is no
standard for signalling for integer types.<

Int NaN ;-)
I guess that 0 is as good as can be done in present state of the world.<

Using int.min instead is another possibility.
I asked the compiler guy for some project to give me a compiler switch to
change all integer types like int to MyTemplate. E.g. Valid. Or to change all
pointer types char* to CheckedPointer. But I think that this would disagree
with D's "no name hijacking, ever" principle.<

Valid === int? in C#.
No eval. I guess I am not surprised... although eval is powerful.<

I think in LDC you can implement an eval() in a simple enough way.
Mark Charney and I bounced words at each other like embeddable, subsettable,
defeaturable. Mark recently changed a big tool from C++ to C to avoid the
overhead of C++ run-time I chatted with BSD kernel guys on same topic. Real
systems programming languages allow stuff to be stripped out, like exception
handling, like GC.<

If the ability to disable those two features, then it may be done: - The exception handling can be disabled, but probably some of the run-time type information can't be removed from D programs. - A compilation flag may be added to not add a GC into the compiled binary, but then it has to produce a syntax error at compile time everywhere the GC is silently used (array length increase, array concatenation, associative arrays, etc).
"Standard library is trusted": this almost set off red flags and alarms for me
as a security guy, since trusting printf like code was one of the classic
Burrough's era security bugs. But I realized that Alexandrescu's "trusted",
from the D language perspective, and my perspective frm the point of view of
real hardware security, is very different. Basically, even though print is
"trusted" as a library, I am still not going to implement printf as a system
call, with the character formatting in the kernel.<

Improving the safety of the C libs of D is a good idea. Just because it is stuff that looks like C doesn't mean it has to be fully unsafe. (I think Walter doesn't agree with me here).
"In module Foo, please intercept all calls to module Bar, and route them
through module BarWithDebugging".<

Cute.
And/or allows separate headers and modules, and enforces compatibility.<

I don't think D does this.
Avoids writing code twice, but permits if you really want that. (Again: I often
create "header only libraries", like Boost. And created the interface generator
for iHDL, I hate writing code twice, even declaration/definition.)<

It seems he's missing the point of a module system like D tries to have (and almost has).
Contracts. Yay! I thought at first it was only a subset of Eiffel contracts,
but it appears complete.<

It's not complete.
Code annotated with keyword unittest can be embedded, and run before main.
Nice. But I started getting afraid of creeping featurism.<

Here featurism isn't the problem, the problem is that people really need something a bit more flexible. I suggest Walter to try to use NUnit of C# or other unit testing systems.
D defines lots of keywords. At the very least, I want to give up on keywords -
require keywords to be distinguished by XML. I'm into post-Ascii languages.<

I think this part of the design of D can't be changed now. So, given the current design of D, having a keyword to represent a different concept is usually better than having keywords like "static" that mean many unrelated things, just to reduce keyword count.
Q: I'm assuming that you can pass structs by ref or pointer... And can
similarly pass class objects by value. But the latter may not be true.<

Indeed, it's false.
Less runtime reflection than C++ or Java.<

Runtime reflection can be improved a little, in D2.
although it is unfortunate, since many parallel programming types like me would
like to use "foreach" to indicate visiting in no particular order.<

At the moment D has little regard for data-parallel numeric programming. It's a matter of targeting D2: if D2 wants to become more appreciated by such people then some things (and compiler optimization guarantees) have to be added. Some of those things can also be provided by libraries (even by Phobos2), but not all of them.
If a regular function is evaluated in a compile time context, the compiler
attempts immediate interpretation. I meant to ask: compiler people have long
known how to do this, but have had a problem: cross compilation. E.g.
evaluating sin(1.0) may give different results on machine the compiler is
running on than on the target. Heck, even integers, since #birs may vary. I
meant to ask if D solved this, a la Java "compile once, run everywhere".<

I think D mostly targets X86. "#birs" I think he meant "#bits", but all D types but "real" are fixed in size.
BTW, Scott Meyers asked if D detected integer overflow. No. I wonder if it
would be legal to create a compiler than detected overflow. In C/C++, too much
code depends on overflow, e.g. shifting bits off top.<

I think it's legal to add integer overflow detection to LDC. A way can be added to locally disable such detection (a pragma, or something with a nicer syntax, I have discussed this in the past).
OK, that wins. But.... are D's scopes first class?<

I think they aren't.
By the way.... if a function or class defined locally refers to a variable in
the surrounding context, and the lifetime survives the context, it can be
converted implicitly to a closure. While this is great, it also sounds like a
big source of bugs, performance, and memory leaks.<

Memory leaks: not that much, I think, thank to the GC. Performance: In theory "scope" may solve the problem in many situations. Bugs: it may lead to bugs only if the compiler doesn't act in a uniform way: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=17166
D has a PGAS-like memory model. (PGAS = partitioned global address space, or,
as I like to say, privae/global address space. See
http://en.wikipedia.org/wiki/Partitioned_global_address_space)<

First time I hear of PGAS. From Wikipedia:>The PGAS model is the basis of Unified Parallel C, Co-array Fortran, Titanium, Fortress, Chapel and X10.< Very good, it's a start to implement some ideas from Chapel :-)
But you can explicitly add a shared keyword.<

And even __gshared.
shared is transitive. Like const leads to C++ const-ipation, shared will have
similar issues. D may ameliorate them via its more convenient generic support.<
I think that any transitive feature suffers const-ipation. Transitive shared or
volatile const-ipation. Sounds disgusting.<

I think Andrei is working on such problems.
Q: how do you say "void f(int a, int b)", where all combinations of shared and
private int a and b are allowed? Sure, *some* folks will just say "cast tio
shared". Shared thread-safe code should be able to manipulate private
variables, right? Except... in PGA supercomputer land private and shared may
use differeht instruction sets. Truly. In fact,. one of my goals is to allow
the same instructions to be used for shared and private.<

At the moment D isn't looking at all at supercomputers. But if D wants to become more appreciated by numerical computing folks then I think it has to keep an eye to the needs of such world too. I think this can also have as side effect to improve D for the future desktop CPUs with 40+ cores (or for the present GPUs with 200+ cores).
Andrei did not talk abot the memory ordering model. Heck, if you define a
memory ordering model, on a weakly ordered machine even ordinary instructions
used to access shared data must have fences added all over. Perhaps this is why
we should encourage transitive shared const-ipation.<

I leave this to other people.
If irt were ubiquitous, I would use it.<

This is a quite positive comment :-)
b) Embeddability/subsettability/defeaturability. I would like to be able to,
e.g. turn off the GC, or turn off the exception handling. I like the idea of a
high level systems programming language, but the OS kernel programmers I know
don't even use C++. They use C. It is not clear that D solves all the problems
that prevent so many OSes from using C++ in the kernel.<

Even if ways are added to totally remove GC and exceptions, I don't know if D is fit for low level purposes like OS kernel programming or embedded CPUs. Overall a nice set of comments, most of them are positive! Bye, bearophile
Jul 18 2009