www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Other notes

reply bearophile <bearophileHUGS lycos.com> writes:
Here are few more notes on the D language, now I know it enough.

1) At the moment this isn't acceptable in D (but the compiler correctly gives
an error instead of doing the wrong thing as some C compilers):

if (0 < a < 5) writefln("***")

Python accepts it and it shows it can be useful (more readable when you define
intervals):

 a = 10
 if 0 < a < 5: print "***"



 a = 2
 if 0 < a < 5: print "***"



*** (D 2.x has intervals, but I think they can't be used here, even if they define the 'in' operator.) 2) This looks like a bug of DMD v1.023, x isn't initialized, and it prints like garbage: import std.stdio: writefln; void main(string[] args) { if (args.length > 1) { switch (args[1]) { int x = 1; // NOT initialized? case "1": writefln("1! x=", x); break; case "2": writefln("2! x=", x); break; } } } 3a) I love the focus D has to avoid bugs, because fixing them sometimes takes more time than writing the program. I think D shows that one of the best ways to avoid bugs is to trash some parts of C and replace them with something better. With time I hope D to remove some of its redundancy too, this means removing some C/C++ ways, like: int array[10]; because I belive in "There should be one-- and preferably only one --obvious way to do it." as the zen of Python says. Cyclone is a language that looks a lot like C, sharing many of its problems, but tries to avoid some common traps (look at the article, it lists some of the things it cheeks): http://en.wikipedia.org/wiki/Cyclone_programming_language D tries to be a fast language, while Cyclone is slower than C/D. A possible compromise (that D seem to already partially use) is to activate those cheeks in development mode, and disable them in the final release. Two large sources of bugs that can be handled that way are integer overflows and broken pointers/references. The Delphi/TurboPascal compiler shows that a compilation flag can be added to D that disables *all* integral (char too) overflow cheeks (they are ON by defaul). This helps avoid silly bugs like this too: writefln("hello".length > -3); (If the compiler is a bit smart it can avoid part of those overflow cheeks anyway, even when they are switched on). The second group of runtime cheeks (on pointers/references) can avoid problems with not allocated objects, wrong pointer arithmetic, freeing random parts of memory, etc, and they can be disabled with -release. (A problem I can see here is that those pointers/references have to become "fat" (because doing a compile time analisys of the code is too much complex), this changes the sizeof of pointers from the development version of the code to the -release version that uses the normal fast thin pointers.) 3b) This D code lacks a ref, maybe the compiler can spot this bug (I have done a mistake like this in the past): int[10] array; foreach(i, el; array) el = i; 3c) This is a bug that Python avoids, because it doesn't use { } to define blocks. In D leading spaces are ignored but they can be used by the compiler to spot this situation and maybe it can issue a warning: if (...) first(); else printf("Calling second()"); second(); 4) Every language feature adds complexity to the compiler, makes the language manual longer, requires programmers to remember more things, etc. So every language feature has to be kept only if enough people use it, without a good way to replace it, etc. I like D real type, but so far I have't found a situation where double can't solve my problem. So who of you is using the real type? If there isn't enough people using it then it may be removed from the D specs. Bye and thank you, bearophile
Nov 24 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to bearophile,

 3c) This is a bug that Python avoids, because it doesn't use { } to
 define blocks. In D leading spaces are ignored but they can be used by
 the compiler to spot this situation and maybe it can issue a warning:
 
 if (...)
   first();
 else
   printf("Calling second()");
   second();

leave that to some sort of "Lint for D"
 4) Every language feature adds complexity to the compiler, makes the
 language manual longer, requires programmers to remember more things,
 etc. So every language feature has to be kept only if enough people
 use it, without a good way to replace it, etc. I like D real type, but
 so far I have't found a situation where double can't solve my problem.
 So who of you is using the real type? If there isn't enough people
 using it then it may be removed from the D specs.
 

I only use real. On most, if not all, systems it's just as fast as double (OK it needs more IO time but...) so why not use it?
 Bye and thank you,
 bearophile

Nov 24 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to bearophile,
 4) Every language feature adds complexity to the compiler, makes the
 language manual longer, requires programmers to remember more things,
 etc. So every language feature has to be kept only if enough people
 use it, without a good way to replace it, etc. I like D real type, but
 so far I have't found a situation where double can't solve my problem.
 So who of you is using the real type? If there isn't enough people
 using it then it may be removed from the D specs.

I only use real. On most, if not all, systems it's just as fast as double (OK it needs more IO time but...) so why not use it?

You answered the question right there. More memory means occupies more cache, more disk etc. I basically only use real for intermediate temporaries where I might want to keep a little more precision. I basically never store reals or pass them between functions. 10 bytes is kind of a weird size for alignment-sensitive things too. But I don't think it needs to be removed from the specs. It's neat you can get at it when you need it. --bb
Nov 24 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Bill,

 BCS wrote:
 
 Reply to bearophile,
 
 4) Every language feature adds complexity to the compiler, makes the
 language manual longer, requires programmers to remember more
 things, etc. So every language feature has to be kept only if enough
 people use it, without a good way to replace it, etc. I like D real
 type, but so far I have't found a situation where double can't solve
 my problem. So who of you is using the real type? If there isn't
 enough people using it then it may be removed from the D specs.
 

double (OK it needs more IO time but...) so why not use it?

more cache, more disk etc. I basically only use real for intermediate temporaries where I might want to keep a little more precision.

point taken
 I basically never store reals or pass them between functions. 10 bytes
 is kind of a weird size for alignment-sensitive things too.
 

I use it for parameters and return values, I would only downsize to double if I'm storing a lot of them. In my cases, my programs tend to be computationally heavy but not very data heavy. Having a few hundred values around at any one time would be unusual.
 But I don't think it needs to be removed from the specs.  It's neat
 you can get at it when you need it.
 
 --bb
 

Nov 24 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Bill,
 
 BCS wrote:

 Reply to bearophile,

 4) Every language feature adds complexity to the compiler, makes the
 language manual longer, requires programmers to remember more
 things, etc. So every language feature has to be kept only if enough
 people use it, without a good way to replace it, etc. I like D real
 type, but so far I have't found a situation where double can't solve
 my problem. So who of you is using the real type? If there isn't
 enough people using it then it may be removed from the D specs.

double (OK it needs more IO time but...) so why not use it?

more cache, more disk etc. I basically only use real for intermediate temporaries where I might want to keep a little more precision.

point taken
 I basically never store reals or pass them between functions. 10 bytes
 is kind of a weird size for alignment-sensitive things too.

I use it for parameters and return values, I would only downsize to double if I'm storing a lot of them. In my cases, my programs tend to be computationally heavy but not very data heavy. Having a few hundred values around at any one time would be unusual.
 But I don't think it needs to be removed from the specs.  It's neat
 you can get at it when you need it.

 --bb


I should also say that A) though I know more than the average Joe about it, I'm by no means an expert on numerical computing. B) my applications are mostly graphics-oriented so a little roundoff is rarely of concern to me. The "eyball norm" is the only error norm that matters for most of what I do. --bb
Nov 24 2007
prev sibling next sibling parent reply Moritz Warning <oh no.es> writes:
bearophile Wrote:

 Here are few more notes on the D language, now I know it enough.
 
 1) At the moment this isn't acceptable in D (but the compiler correctly gives
an error instead of doing the wrong thing as some C compilers):
 
 if (0 < a < 5) writefln("***")

but in generalization. But it may be hard to implement...
 2) This looks like a bug of DMD v1.023, x isn't initialized, and it prints
like garbage:
 
 import std.stdio: writefln;
 void main(string[] args) {
   if (args.length > 1) {
     switch (args[1]) {
       int x = 1; // NOT initialized?
       case "1": writefln("1! x=", x); break;
       case "2": writefln("2! x=", x); break;
     }
   }
 }

[snip]
 3b) This D code lacks a ref, maybe the compiler can spot this bug (I have done
a mistake like this in the past):
 
 int[10] array;
 foreach(i, el; array)
     el = i;

int[10] array; foreach(i, inout el; array) el = i; Works. :)
 

[snip]
 4) Every language feature adds complexity to the compiler, makes the language
manual longer, requires programmers to remember more things, etc. [...]

Imho, that is not the case every time. Features may also mean generalisation that elemitates complexity. E.g. allowing to pass global&&compile time values to the compiler for the "debug" and "version" keyword could be generalized and would therefore satisfy a good amount of requested features and also remove keywords/documentation.
 
 Bye and thank you,
 bearophile

Nov 24 2007
parent reply Moritz Warning <oh no.es> writes:
Moritz Warning Wrote:

 bearophile Wrote:

 3b) This D code lacks a ref, maybe the compiler can spot this bug (I have done
a mistake like this in the past):
 
 int[10] array;
 foreach(i, el; array)
     el = i;

int[10] array; foreach(i, inout el; array) el = i; Works. :)

What if you want to just some stupid benchmarking? The decision if this does or does not have an effect (and therefore would be an error) may be a subject of a boring discussion. ;-)
Nov 24 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Moritz Warning wrote:
 Moritz Warning Wrote:
 
 bearophile Wrote:

 3b) This D code lacks a ref, maybe the compiler can spot this bug (I have done
a mistake like this in the past):

 int[10] array;
 foreach(i, el; array)
     el = i;

foreach(i, inout el; array) el = i; Works. :)

What if you want to just some stupid benchmarking? The decision if this does or does not have an effect (and therefore would be an error) may be a subject of a boring discussion. ;-)

I use the iteration variable as a temporary sometimes. I would be annoyed if the compiler tried to 'detect' that for me. Dave
Nov 24 2007
parent reply bearophile <bearophileHUGS lycos.com> writes:
Thank to everyone for the answers and comments.

BCS:

leave that to some sort of "Lint for D"

I agree that certain things are better left to a lint (because for example a static analysis of the code can be quite slow and complex, so it may make the compiler too much slow and complex. And some of those things may make its command line too much hairy, and some of those things may be a bit controversial), but there are other things better left to the compiler (optional integral overflow cheeks, warnings issued for unused variables/classes/functions, optional accurate pointer/reference cheeks. I think all three of them are quite important, and the first two are commonly found in other languages too (like Delphi and C#)).
I only use real. On most, if not all, systems it's just as fast as double (OK
it needs more IO time but...) so why not use it?<

Maybe to help the port of D to different not-Intel CPUs, but I am not expert about this. ------------------- Moritz Warning:
Features may also mean generalisation that elemitates complexity.<

You are right. (The following note is a bit unrelated) But I have seen languages like Scheme where most things are very general, you can combine them in every way; the net result is that people write quite unreadable programs because such people find really twisted ways to nest and mix those things (think of the Y combinator). Python on the other hand offer some general tools, but such tools aren't too much general, so they must be used for a certain class of purposes, so the resulting code is readable, beucause you can't nest things too much and you can't combine them in totally novel ways every 5 lines of code. There is a balance between a language too much tailored and one where you can do everything, both extremes are bad (too much flexible or too little flexible, you may also say). Scheme (and maybe Haskell), Cobol, Fortran (and maybe the first versions of Pascal) are near one corner or the other, while Python (and maybe D) seems closer to the the middle. (But note that some programming fields and some programmer minds are more fit for a more flexible or for a less flexible language, so no language is fit for everything and everyone).
Well.. I guess it's hard to spot for the compiler that there could be an error.<

I see, this specific thing may be better left to a lint program. ------------------- David B. Held:
I use the iteration variable as a temporary sometimes.  I would be annoyed if
the compiler tried to 'detect' that for me.<

I see, it may be too much difficult to spot such things. Another thing for a lint, then. Bye, bearophile
Nov 25 2007
parent BCS <ao pathlink.com> writes:
Reply to bearophile,

 Thank to everyone for the answers and comments.
 
 BCS:
 
 leave that to some sort of "Lint for D"
 

example a static analysis of the code can be quite slow and complex, so it may make the compiler too much slow and complex. And some of those things may make its command line too much hairy, and some of those things may be a bit controversial), but there are other things better left to the compiler (optional integral overflow cheeks, warnings issued for unused variables/classes/functions, optional accurate pointer/reference cheeks. I think all three of them are quite important, and the first two are commonly found in other languages too (like Delphi and C#)).
 I only use real. On most, if not all, systems it's just as fast as
 double (OK it needs more IO time but...) so why not use it?<
 

expert about this.

real is defined as the largest hardware supported floating point type. That would be /smaller/ than double on a system with only 32bit FP hardware.
Nov 25 2007
prev sibling parent torhu <no spam.invalid> writes:
bearophile wrote:
 Here are few more notes on the D language, now I know it enough.
 
 1) At the moment this isn't acceptable in D (but the compiler correctly gives
an error instead of doing the wrong thing as some C compilers):
 
 if (0 < a < 5) writefln("***")

The behavior of the comparison operators was changed in dmd 1.007, so that they later can be changed to the behave the same way as in python. At least I think that was the idea.
Nov 25 2007