Subject: Re: [RFC] Convert builin-mailinfo.c to use The Better String Library.

From: Walter Bright <[email-masked]>
Date: Fri, 07 Sep 2007 13:22:53 -0700

David Kastrup wrote:
> Again, C won't keep you from shooting yourself in the foot.

Right, it won't. A good systems language should do what it can to 
prevent the programmer from *inadvertently* shooting himself in the 
foot, while allowing him to *deliberately* shoot himself in the foot.

In the example loop, the cases I pointed out were ones where, if one 
changes part of the code (such as the array dimension, or the array 
type, etc.), then there are multiple places in the source that must be 
updated to reflect it. The reality of human programmers is we update one 
or two places, and overlook the third place, and we now have a bug. 
Saying that one should just be a better programmer and not make such 
mistakes is a pipe dream.

Ideally, each facet of the design of the code should have a single point 
where it can be changed, and then all dependencies on that design should 
be automatically updated. That way, nothing gets overlooked. Doing this 
in C, such as using a #define for the array dimension, involves extra work.

It's a truism that if it involves extra work, then it often gets omitted.

Doesn't "A design is perfect not when there is no longer anything you 
can add to it, but if there is no longer anything you can take away." 
apply here? Going from:

  void foo(int array[10])
  {
     for (int i = 0; i < 10; i++)
     {   int value = array[i];
         ... do something ...
     }
  }

to:

  void foo(int[] array)
  {
    foreach (value; array)
    {
      ... do something ...
    }
  }

takes a lot of frankly unnecessary things away, each of which is a 
potential source of error when maintaining the code.

> No, because programmers get things wrong.

Exactly. That goes back to my point that a good language should help 
prevent inadvertent errors, while still allowing deliberate choices. D 
approaches this by making the correct approach essentially be the one 
with minimal typing effort. To deliberately shoot yourself in the foot 
usually requires extra typing. For our loop example, we can still write 
the C style loop (with all its potential problems) in D, but it requires 
extra effort to put in those potential problems. The easier, simpler way 
doesn't have the problems.

(The issue I have with C++'s fixes to various problems is they require 
extra typing (like the loop example), so guess what, people being people 
tend to not use them. This results in endless attempts to try and push 
C++ programmers into using the more verbose forms, a strategy I suspect 
will be ultimately futile.)

> You can tell C compilers to
> check all array accesses, but that is a performance issue.

Runtime checking of arrays in D is a performance issue too, so it is 
selectable via a command line switch. But more importantly,

1) Static type checking of fixed size arrays works, so errors can be 
caught at compile time.

2) For dynamically sized arrays, the dimension of the array is carried 
with the array, so loops automatically loop the correct number of times. 
No runtime check is necessary, and it's easier for the code reviewer to 
visually check the code for correctness.

------
Walter Bright
http://www.digitalmars.com  C, C++, D programming language compilers
http://www.astoriaseminar.com  Extraordinary C++