On Sun, May 26, 2013 at 01:13:30PM +0200, Paulo Pinto wrote:
[...]
Now it is too late for it, but at the time C could have stayed as
powerful as it is while offering:
- proper modules, or at least namespaces
- no automatic conversions between arrays and pointers. how hard it
is to write &a[0]?
I think this was a historical accident. The original C, being an
abstraction of assembly, simply inherited the convention of using a
memory address to refer to some data, be it singular (pointer) or plural
(array). Of course, in retrospect, this conflation was a bad idea, but
it's not surprising why this choice was made.
- arguments by reference, no need to check for null for every parameter
Again, this was a historical accident. In assembly, there is no
distinction between a pointer and a reference, so it's not surprising
why the inventors of C didn't make that distinction also. In retrospect,
of course, this would've been a huge improvement, but as they say,
hindsight is always 20-20.
- strong typed enumerations
I've always been on the fence about this one. I wonder how things would
have turned out if Kernighan and Ritchie had made a distinction between
proper enumerations (nothing outside of the set is allowed) and what's
essentially an int with named values (values outside the set of names
are allowed). I find that a lot of C code actually want the latter, not
the former, esp. with bitfields.
- memory allocation without requiring the developer to use sizeof
everywhere
And typecasts everywhere. I mean, seriously, it's so incredibly annoying
to keep writing:
myLongNamedType *t = (myLongNamedType *)malloc(sizeof(myLongNamedType)
* n);
if (!t) { ... }
...
over and over and over. Talk about verbosity. (And this isn't even
Java!)
In retrospect, though, I can understand why it was done this way (malloc
was just another library function), but again, hindsight is 20-20. Back
then there was a lot of pressure to minimalize the language; nowadays we
know better, and realize that certain things, like memory allocation,
really are much better handled within the language itself.
- strings similar to what D has
Yeah, ASCIIZ was both a blessing and a curse. A blessing in that you
don't have to keep passing a length around; a curse in that sometimes
passing a length around is the right thing to do.
- proper arrays, after all the compilers for other languages always
offered control over when bound checking code was generated
Well, in those days, premature optimization was king, and I can see why
C went the way it did. Saving every last byte was always a top concern,
even if today we scoff at it (and rightly so!). Time proved, though,
that ultimately we *had* to keep the length around for various reasons
anyway, so in retrospect they should've been included in the first
place.
In the end, same syntax, just some semantic improvements on the type
system.
But now it is too late, we only have modern C++ with its warts, or
hopefully D, Rust, Go, C#, or something else as possible
replacement.
However, given that C and UNIX are one and only, it will outlive us all.
[...]
I don't know, if we get our act together in polishing up D, we may yet
live to see the rightful demise of C (or more likely, its fading into
the obscure dusts of time). I'm hopeful, anyway. :)