For years the development scene has been dominated by the C family of languages, primarily C itself and its immediate successor C++. Recent years have given rise to other C-descendents, however, such as Sun’s Java and Microsoft’s C#.
Nowadays we here lots of hype about .NET and J2EE, lots of propaganda about how both C# and Java are "The Way of the Future." But as we all know, sometimes the real gem is the unsong underdog, the one that don’t have full page ads in tech journals. And today I’m going to take a look at one such gem: The D Programming Language.
What is D?
D is a (relatively) new addition to the C family of programming languages, intended as a successor to C++ but also incorporating ideas and improvements from other C-like languages such as Java and C#. It is an object-oriented, garbage-collected, systems programming language that is compiled to executable rather than bytecode. The specification and reference compiler are currently at version 0.82, and are expected to reach 1.0 within the year. The reference compiler runs on both Windows and Linux x86, and the frontend if Open-Sourced. A port of the frontend to GCC is underway and already functional on Linux x86 and Mac OS X.
Maintained by Walter Bright, author of the Digital Mars C/C++ compilers and former compiler programmer for both Zorland and Symantec, is the language’s primary author and maintains the reference implementation, though most if not all language decisions are made only after discussion on the D newsgroup. (See links at the end.)
How’s That Different Than What We Had Before?
C++
D is designed to address the shortcomings of C++. While a powerful language, years of history and unneeded complexity has bogged down that language. Five years after the language’s standardization, most compilers are still struggling to become compliant. While C++ pioneered in generic programming and brought objects to the masses, its complexity makes it very hard to add new features, and so it lags behind in newer techniques such as design-by-contract, unit-testing, and include dependency resolution.
In most respects, however, D functions like C++: most C++ code can be converted directly and will, generally speaking, function as expected. Perhaps the largest change in D is the addition of automatic garbage collection, though explicit delete statements will still function as they do in C++.
Java
While not the direct parent of D, many of Java’s techniques have been incorporated into it. Some claim that D’s object definition syntax is more similar to Java’s, though it really ought to be familiar to any modern object-oriented programmer.
In terms of similarities, D and Java are both garbage-collected, both do not make a distinction between the ".", "->", and "::" operators, both include null as a keyword, and both feature try-catch-finally exception handling. Also D’s module system of includes is similar to Java’s packages. As to differences, D is compiled to an executable instead of bytecode, and is not as rigidly object-oriented. Unlike Java, D does not force the object-oriented paradigm on the programmer and can be used just like procedural C. Finally, D allows (but does not encourage) pointer manipulation.
C#
C# and D are really both answers to the same basic question: How can we improve C++? Both are derived from C++ with specific elements drawn in from Java. Both share most of their major features. The biggest difference is that unlike C#, D does not run inside a VM, and can thus be used to write systems (low-level) code. This also allows D to offer the programmer the options of performing manual memory management, which C# does not, nor does C# have anything like D’s templating capabilities, which are on par with C++’s.
OK, What Does It Do?
Having now established what D is not, it might serve us well to note what D is, and to examine some of its features:
Binary C Compatibility
D programs can import and link against C code and libraries, providing D with free access to a huge amount of pre-written code. Note, however, that D is not link-compatible with C++, so pure C wrappers are required to access C++ code in D.
Systems Programming
Because D is compiled to binary rather than bytecode, and it does not run inside a virtual machine, D can be used for systems and low-level programming. It allows in-line assembly, and the garbage collector can be regulated (or even disabled) if real-time capabilities are necessary.
Lexicial, Syntactic, and Semantic Clarity
One of the major goals of D is to eliminate a lot of the complexity of C++ that has made it so hard for compilers to live up to the standard. A simplified syntax makes the job of both the compiler and the programmer easier, as it allows compilers to be more efficient and reduces the likelihood of compiler bugs. As an example, D drops the much-contested angular bracket syntax for declaring templates, making code easier both to read and parse.
Design-by-Contract and Automatic Testing
D advocates the use of design-by-contract and provides built-in facilities for automatic unit-testing. While both are technically possible in C++, D makes them core tenets of the language to make them easier to use for novices. The hope is that with testing built into the language bugs will be easier to identify and fix, especially if programmers get into the habit of using the testing features.
Removal of Archaic Features
Probably the language’s greatest goal is the elimination of archaic and/or needlessly complicated features. For instance, D does away completely with the C preprocessor, relying instead on built-in versioning capabilities. Forward declarations are out the window on the same token. Also, it replaces the often-complicated multiple inheritance of C++ with Java’s single inheritance and interfaces. Most of these features are also related with the above of clarity, making the code easier for a human to read as well as easier for a compiler to convert into binary.
These are by no means the only features of D, but for the sake of brevity I shall leave the exploration of the others as an exercise for the reader. For more information, see Walter’s SDWest paper.
So What Does It Look Like?
<pre> //Copyright Walter Bright. Used with permission.
import std.c.stdio;
import std.file;
int main (char[][] args)
{
int w_total;
int l_total;
int c_total;
int[char[]] dictionary;
printf(" lines words bytes file\n");
foreach (char[] arg; args[1 .. args.length])
{
char[] input;
int w_cnt, l_cnt, c_cnt;
int inword;
int wstart;
input = cast(char[])std.file.read(arg);
for (int j = 0; j < input.length; j++)
{
char c;
c = input[j];
if (c == '\n')
++l_cnt;
if (c >= '0' && c <= '9')
{
}
else if (c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z')
{
if (!inword)
{
wstart = j;
inword = 1;
++w_cnt;
}
}
else if (inword)
{
char[] word = input[wstart .. j];
dictionary[word]++;
inword = 0;
}
++c_cnt;
}
if (inword)
{
char[] w = input[wstart .. input.length];
dictionary[w]++;
}
printf("%8lu%8lu%8lu %.*s\n", l_cnt, w_cnt, c_cnt, arg);
l_total += l_cnt;
w_total += w_cnt;
c_total += c_cnt;
}
if (args.length > 2)
{
printf("------------------------------\n%8lu%8lu%8lu total",
l_total, w_total, c_total);
}
printf("--------------------------------------\n");
foreach (char[] word1; dictionary.keys.sort)
{
printf("%3d %.*s\n", dictionary[word1], word1);
}
return 0;
}</pre>
This program should look familiar to most C/C++ programmers: it’s the classic "word count" program. While most of it should be easily comprehensible to anyone versed in C-like languages, I will highlight a few features:
<pre> import std.c.stdio;
import std.file;</pre>
These lines are D’s version of includes. The first imports the plain C stdio functions (notably printf), while the second imports the D standard library (known as Phobos) file I/O systems.
<pre> int main (char[][] args)</pre>
You’ll notice here and throughout the program that D uses neither char* nor a string class for string values. D arrays are "smart arrays," which know their own length and are capable of most of the functionality of C++’s various STL array types.
<pre> int[char[]] dictionary;</pre>
This declaration will look odd to C++ programmers, but it is in fact a familiar concept: it creates an array of integers that is indexed by strings, called an associative array. This is equivalent to Maps in both STL and JFC, but in D it is a core language feature rather than part of the standard library.
<pre> foreach (char[] arg; args[1 .. args.length])</pre>
This line illustrates two new features of D: foreach
and slicing. foreach
replaces the need for iterators, as arg
will take on the value of each element in the array as the loop executes. This is guaranteed to be in order if using a standard array, but no order guarantee is made for associative arrays. Slicing is the ability to declare an array as a subarray of another. In this case, args[1 .. args.length]
is the subarray of args that includes all elements except the first. You can also note here that args, an array, knows its own length.
<pre> foreach (char[] word1; dictionary.keys.sort)</pre>
Any array of entities that defines a comparison operator is sortable, such as the array of keys of an associative array. Again, this is a language feature rather than part of the standard library.
Beyond This Article
This article does not even begin to examine all the features of D. For instance, the above example program does not make use of any of D’s object-oriented features, nor its generic programming capabilities, nor its built-in testing facilities. While all are certainly worthy of note, covering all in one article would be over-ambitious. Instead, here is a list of references where more information about D can be found:
The D Specification (Working Version)
The D Compiler (Linux and Windows)
The D Newsgroup (D Language Features Discussion)
The D.gnu Newsgroup (D for GCC Discussion)
The D Frontend for GCC (Work in Progress. Supports Linux and Mac OS X thus far.)
DSource.org (Newly formed host for D projects. Also hosts tutorials.)
D Links (Large list of D sites and libraries)
About the author:
The author, Owen Anderson, is a Computer Science student at Macalester College. He develops for Mac OS X and Linux, and has recently started the Docoa project to bridge D to Objective-C on Mac OS X.
If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
We’re having PowerD from some time on AmigaOS. Same goes for E. 🙂
While this looks great and all, it seems that its unnecessary. There has always been this speration betwee asm|C|C++|C#|JAVA and to squeez D between C++ and C# seems a stretch especially since people such as myself are just starting to enjoy c#. This is a strech because C++ is fast and low level, and even though c# is interpreted, it is still a fast enough interpretation to be low enough (I.E. Its not java). The ONLY way i see myself typing a line of that D (my current gpa) code would be if Microsoft threw it in as a core language with lots of intellisense and documentation in Visual Studio, Which i do assert would not be a bad thing. Who’s with me?
What about Objective-C?
What’s the real difference between D and ObjC (aside from the letters)?
$
I looked at the code and noticed that they had done away with the istream and ostream operators.
I am sorry, but the printf and scanf functions suck. iostream objects make writing code much easier in my opinion.
Well, C# has to be (aroud) halvway to D from C…
C * 2 ^ (1/12) = C#
C# * 2 ^ (1/12) = D
(if the scale is non-harmonic)
re: pass.
Just because something is fast, does not mean it is low-level. For instance, in C# you can’t directly access the hardware. Most people don’t need this feature, but for those that do it’s a must and C# is not sufficient for their needs. (Although, I think you can do inline assembly in C#, but I’m not too sure since I mostly stick with C++.)
re: So then…
Objective-C is supposed to be as close to C as possible. They added maybe 4 keywords to C. D is meant to be a successor to C++. As the article says it takes C++, cleans up some features, and adds some nice features from Java/C# (most notably in my mind is garbage collection). Think of Objective-C as what C++ started out as — C with classes, and D as a next-gen language that keeps with the C/C++ mentality (low-level).
“[…] nor does C# have anything like D’s templating capabilities, which are on par with C++’s.”
While I am not familiar with D’s templating capabilities, I’d like to mention that C# gets generics with version 2 as anyone and his mother should be aware of by now. I assume you are referring to versions < 2 and don’t want to imply that C#’s forthcoming generics are somehow inferior to D’s templates.
I was a big standoff on C++, until I started using it more. Now I love the simplicity of cout/cin and so forth. Although, it is very nice, I find myself using my old standby getch() a lot. It’s great for just pausing and waiting for a user to continue on with the program.
But,
cin >> age >> sex >> location;
is way cleaner than
scanf(%i%c%s”,&age, &sex, &location);
Of course neither way is really the best since neither does type checking or any other sort of bad-data checking, but hey it’s a simple example.
I forgot a ” mark, should read:
scanf(“%i%c%s”,&age, &sex, &location);
I read the source code and it looks a little strange..
================================
if (c >= ‘0’ && c <= ‘9’)
{ /* empty here? */
}
else if (c >= ‘a’ && c <= ‘z’ ||
c >= ‘A’ && c <= ‘Z’)
{
================================
Write a kernel (maybe a full OS) in D will be very interest.
Check out:
http://www.digitalmars.com/d/comparison.html
D allows operator overloading, so it should allow istream and ostream operators if you really want them.
<sign> My subject was supposed to be: Does it works on BSD?
Good article…
Yet, like the author mentions, this article barely touches the surface of D’s features. The language libraries are still in development and that includes the stream operators. There are some stunning stream solutions available and in the works that demonstrate D’s OO capabilites. The printf is just an “old faithful” and does not represent D’s future at all. This rather demonstrates D’s backward compatibility with C.
Glancing at code and making a conclusion does not consitute a thorough assessment of a language with great potential. 🙂
I slightly disagree with the author about D functioning like C++. Though there are some similarities in inherited c traits in both, programming is decidely different. It’s much less complicated in D while maintaining what might be considered equivalent power. OO programming in D has some similarities but only in to a limited extent.
Check out the links provided by the author to get a better feal… http://www.dsource.org has some more tutorials demonstrating it’s power.
D also makes for an excellent game development language. OpenGL, SDL, glfw, glee, directx9 have all been made accessible to D in one way or another.
GUI toolkits are present for both windows and linux (DUI for windows and linux is a gtk+ OO interface for d — see dui.sourceforge.net; dig for windows; and others). More are in the works (DWT, a SWT port). Well designed, high performance server/socket libraries are also being developed.
This language is growing, growing, growing.
Any self-respecting successor-wannabe to C++ would be named ‘L’, since ‘C’++ is ‘P’ already… (if you ignore the const-ness of ‘C’… 😉 )
I am waiting to see how D shapes up. Walter Bright is one of the best compiler people, so I think we’ll end up with “the language C# should have been”.
Having used C# a fair amount recently, I went from neutral on it to “wow, this is far worse than C++, just in a different way.” C# is not for thinking people. D is.
Thank you Walter et al.
For whatever it’s worth, D is also the programming language in DTrace, a new instrumentation facility in Solaris 10. (See http://www.sun.com/bigadmin/content/dtrace for details.) I’m not sure which came first (we started on our D in 2001; this D may well predate it), but hopefully there won’t be too much confusion: the D in DTrace is only a monitoring language, not a general-purpose programming language. (It is C-like, however,and has most C constructs — plus several that are specific to DTrace.) And like the D mentioned here, we have printf() in our D as well — so I guess by the metrics of an earlier poster, our D sucks too…
Thanks for the info man.
I’ll just keep with Obj-C/C++ then.
Perhaps when D becomes a standard, I’ll take a good long look at it.
$
Some practical OSS samples of D, along great innovative games from shoot’em-up guru “ABA games” at http://www.asahi-net.or.jp/~cs8k-cyu/index_e.html
Visit it even if you have zero interest in programming. The games are great.
I think the C# generics are somehow better from an implementation view than Java generics, but don’t think there is much difference between Java and C# generics from a developper point of view, C++ and D templates allow latent typing: http://mindview.net/WebLog/log-0050
The framework (gui, files, socket, thread, database, I/O) is almost as important as the language itself. I hope D will include a portable framework, à la C#/Java. This is where C++ has failed : take string for instance: C-style, STL, MFC, QT, wx… Idem for vector, gui, and so on.
Type introspection is one of the useful things about Java and C#. Does anyone know if D support this?
Does anyone know if the Gnome guys have looked into D as their future language ? Is there any reason why D wouldn’t be suitable ? I haven’t used D my self, but from looking over the DigitalMars page, it looks quite nice, providing the advantages over C some Gnome people are looking for (higher level than C, garbage collection, …) And most importantly, there should’t be any patent or other legal problems with using it.
I still like eiffel and c++ better. Interfaces are an hack
I don´t know where to start. The author complains about the complexity of C++ and suggests a language D to solve the problems in C++. He provides sample code in D, that, upon examination, looks so C-ish, that one wonders whether the author has even taken a look at C++ before.
To put it straight: If the example is the hallmark of “decomplexified” D-Code, you have a lot left to improve. First, i would suggest to check out, what´s possible in C++.
The canonical word-count program would like this in C++:
(and for the ever-complaining pointers-are-evil,c++-buffer-overflow,no-garbage-collection-mafia: take a close look how many pointers there are, how much memory is forgotten to be deleted and how many lines it took)
—-
void print( std::pair<std::string, unsigned int> pair )
{
std::cout << pair.first << ” ” << pair.second << std::endl;
}
int main( int argc, char **argv )
{
std::ifstream iff( argv[1] );
std::map<std::string, unsigned int> map;
std::string str;
while( iff >> str )
map[str]++;
std::for_each( map.begin(), map.end(), print );
return 0;
}
—
I think I prefer D.
After looking a bit more from links in the articles. I realize that D has NO similarites to Java apart from a Garbage Collector.
And D is not as simple to read/understand as Java as well.
And with a special Linker/compiler you could compile C# into binary. Althought i can’t remember the product name for now.
For a new Low level program it could be useful. But on higher level like Java i doesn’t think it is any use at all when C# and Java is already here. With GCJ / Classpath is improving everyday. You could compile Java into binary b4 long.
I think my subj. says it all 🙂
If I should go and learn D, which I’m tempet too, there are one thing what I just want to know. Can I use C++ libraries, like Qt(okay Qt isn’t true C++ but anyway) and GTK+?
I looked at the code and noticed that they had done away with the istream and ostream operators.
——–
You might want to look into DSC.IO on dsource.org. printf/scanf are in fact not reimplemented in D, but making use of D’s C link-compatibility to save having to rewrite them while the language was still in development.
There’s some talk of merging DSC.IO into Phobos when it’s more finished. There’s also talk of merging in a DTL library that I hear is approaching a beta stage. Either way, the standard library is expected to improve significantly between now and the 1.0 release, now that the language itself is stable.
You can not have a garbage-collected system-mprogramming language. Garbage-collection is fine for some GUI operations, and other non-critical applications, but in a kernel it is just not an option. There is absolutely no way D can be classified as a system-programming language, but I wish it all of luck to compete against compiled Java and C#.
If I should go and learn D, which I’m tempet too, there are one thing what I just want to know. Can I use C++ libraries, like Qt(okay Qt isn’t true C++ but anyway) and GTK+?
Well, according to the article, D is link-level binary compatible with C, but not with C++. So to use Qt you’d have to wrap it in C and then wrap it in D. This is possible, but kind of ugly and I don’t know how much of OOP will still work if you do this. GTK+ will work just fine however, since it is written in C for exactly this reason. C is the lowest common denominator for just about every language binding. This is why GTK+ has more mature language bindings that QT for Perl, Python, and other scripting languages.
You can not have a garbage-collected system-mprogramming language. Garbage-collection is fine for some GUI operations, and other non-critical applications, but in a kernel it is just not an option. There is absolutely no way D can be classified as a system-programming language, but I wish it all of luck to compete against compiled Java and C#.
Yeah, that’s why D allows you to turn garbage collection off. So yes, it is still a system-programming language, even by your criteria.
However, technically garbage collection does not prevent you from creating a kernel. True, it will slow the performance of your kernel down considerably, but it won’t make your computer crash, blow up your hardware, or do anything else that is serious. In fact, there was a story posted on OSNews not too long ago about an OS that is being written in Java. I think it was called JNode.
I think D is definitely something to watch for. Syntax looks a little more sane than Obj-C and C++ and performance has to be better than Java and C#. <ducks/>
Could you not just manually delete objects like in C. I think the author mentions using ‘delete’. Not sure if you could turn off garbage collection.
> In D, an empty string is just null
Ouch! There is a very big difference between “nothing/unspecified” and “a string with the length 0”. Trying to make these equivalent is just stupid, and it _will_ come back and haunt you.
Could you not just manually delete objects like in C. I think the author mentions using ‘delete’. Not sure if you could turn off garbage collection.
—-
You are correct. Both are possible. You can disable the garbage collector if you know you don’t want it at all, or you can just use the delete operator in instances where you need guaranteed deletion.
Ouch! There is a very big difference between “nothing/unspecified” and “a string with the length 0”. Trying to make these equivalent is just stupid, and it _will_ come back and haunt you.
——
You’re right. Assuming the underlying structure of the string isn’t a great plan. However, D strings, because they are just arrays of chars, know their own length. Hence you don’t need to and probably shouldn’t rely on the null byte to mark the end.
This article is quite infactual in the C#/D comparison. For starts, C# is quite capable of being compiled to machine code. Mono supports AOT (Ahead Of Time) compilation, and I believe Microsoft’s .NET implementation does as well. These compilers can be just as fast as any D (or even C/C++) can come up with, since the language doesn’t have an inherent reason why it can’t. (Unlike Java which is missing a number of features to make very high speed compiled machine code possible.)
Second, the new version of C# does indeed have Generics, which both Microsoft and Mono support.
C# allows manual memory management. It’s called unmanaged code, and can be mixed with managed code. You can even do pointer arithmetic and the like. The features must be specifically requested, which is a good thing, because it prevents accidents from occuring, which even 20+ year veterans of C/C++ can still easily make.
C#/D are pretty functionally equivalent. C# is on the better side, however, as it already has both popular and Free implementations available, has a number of user and books/references available, and is standardized with ECMA. The small handful of advantages D retains really don’t outweigh those.
Get your head out of your ass. There have been lots of kernels built with garbage-collected languages. The most notable is probably the Lisp machines, which had kernels written in Lisp. Others GC’ed languages used for kernel development include: ML, Scheme, Java, and others.
It should be noted that to use a GC in the kernel, you just have to be a bit smart about your code. The kernel needs to be preemptible, and you need to disable garbage collection while holding a spinlock. It should be noted that in modern kernels, its a bad idea to do memory allocation inside a spinlock anyway, because the memory allocator could block, causing a deadlock.
<sign> My subject was supposed to be: Does it works on BSD?
Should mod this guy up for leaving out the BS.
It should also be noted that advanced GCs give you a lot of flexibility. Take, for example, the MPS (Memory Pool System):
http://www.ravenbrook.com/project/mps/doc/2002-01-30/ismm2002-paper…
It allows for multiple pools of memory to exist for different purposes. Eg: you can have a generational GC’ed pool for general-purpose allocation, a manual heap for objects that should not be collected, a special slab allocator pool for fixed-sized objects, etc. Since a kernel allocates mainly fixed-size objects (see Linux’s slab allocator) you could use the pool allocator for most allocations, and use the GC’ed heap for temporary objects. Since the heap would then be quite small, GC would take almost no time at all, and latency would not be a factor.
@the_trapper: It should be noted that there is no reason to believe that a GC would slow down a kernel any more than it would slow down a regular program, which is little to none. It would probably have a significant impact on latency, but you can get around that by disabling GC on critical paths.
> However, D strings, because they are just arrays of chars,
> know their own length. Hence you don’t need to and
> probably shouldn’t rely on the null byte to mark the end
I wasn’t. The problem is that apparently an empty char array is equal to no array at all. This is clearly a Bad Thing(tm) since there is very much difference between ‘str=””;’ and ‘str=null;’. E.g. in java you can do this ‘char[] str=new char[0];’ which will get you an empty array, which is a completely other thing than just ‘char[] str=null;’ or ‘char[] str;’.
Frankly, C# is a no-go in my opinion as it is a Single-Sourced language. Sorry, seen what happens with those.
C and C++ and Objective-C: I have always loved C. Objective C is my choice for class based software (beats the hell out of C++). C++ if I am required to write for a MS platform. Can’t spare the brain cells if MS decides to deep-six C# (don’t say it can’t happen, MS has done this in the past).
D will have to wait for now. There are plenty of languages out there already. I have yet to see one that “cures” all faults without introducing ones of its own.
“Any self-respecting successor-wannabe to C++ would be named ‘L’, since ‘C’++ is ‘P’ already… (if you ignore the const-ness of ‘C’… 😉 )”
Funny you should mention ‘L’. 😀
What exactly is Java missing that doesn’t allow it to be efficiently compiled to native code?
With all this spagetti soup, I don’t think it helps to just pick a letter like D as a name. Although the D author credentials look good, the company behind C++,Java,C# have far more resources to makes their langs stand out and get books written and mass marketing, education & so on.
Still there is room for minority languages that serve a purpose where the above don’t, but D seems to be a fairly small improvement with some losses. I don’t like having my #preprocessor taken away, stops me dead from any language without it.
In my work on chip design, I would like in the language basic int types of any size upto millions of bits if need be with all operators valid on them and quite a few more. That forces me to use C like HDLs which generally run slower than C by 10-100 fold. I would die to be able to write C with some HDL syntax, best of both worlds, speed & conciseness.
For instance a group of wires on the left is assigned a group of results on the right but not of same width pattern.
{ a,b,c } = { <expr>,….. }
all the right sides are evaluated and the bitwise concatted result is assigned to the bit wise concatenation of a,b,c
Of course you can do this in C indirectly but it introduces >>, &ing to pull groups apart, do work and rejoin and on lots of separate assigns. The total widths maybe far greater than basic int type size.
{ a,b,c } <= { <expr>,….. }
In this form the <= assignment means nonblocking, the result is assigned to the left side not just after the eval, but is held over until the enclosing block ends.
There are plenty of other HDL ideas I could take from Verilog too, such as the parallelism model, such a language might be called V or V++, but another V already exists, guess I’l have to be more creative.
So a hybrid of HDL with C would seem valuable to me but not perhaps to most C users unless you want arbitrary width math too.
regards
JJ
There is still no ‘typeof’ operator to compliment
‘sizeof’. Stll no ‘anytype’ type definition.
ie:
anytype func_any(anytype a)
{
if(typeof(a)==int)
{
//perform an integer operation
b=new int[4];
return b;
}
}
Oh well, wait another 30 years I guess….<sigh>
pete
Last time I used VS.NET, this was not true, thought admittedly that was not the most recent version. And last time I checked, the major feature of C# WAS the CLR, which is not a natively compiler format. That’s like saying the Java can be compiled to native code: it can be, but it’s not meant to be. There are bytecode->executable compilers out there, but it’s not what’s intended to happen nor what is guaranteed to work. I am not well-versed in Mono, so I’ll take your word that it compiles to native binary.
As to manual memory management, you are wrong. I suggest you research the problem of deterministic destruction in C#. Due to the extremely limited ability of the programmer to control memory management, deterministic destruction is nearly impossible. Sorry, but I did a significant amount of research on THAT statement.
Finally, there IS a free implementation of D available: cf. the D for GCC project I referenced in the article.
There’s one key difference: accessing the length property on a null object will throw an exception, while the length of an empty string will be 0.
That’s not true. There IS a typeof operator in D. Please look at the last section of the Declarations section:
http://www.digitalmars.com/d/declaration.html
Since some of you mentioned AOT in mono, could someone explain me how to do it?
I’ve tryed the -aot option, but it just creates an .so that doesn’t run (generates a fault). Could someone explain me how to make use of mono’s AOT?
Although Groovy http://groovy.codehaus.org/ classifies itself as an ‘agile’ language (inspired by python and ruby), it runs on java byte codes and intends to (eventually) be backward compatible with the java language. It has some D-like constructs and the authors of D might find it interesting to take a look at Groovy.
Likewise with jdk 1.5 http://java.sun.com/j2se/1.5.0/download.jsp which has some syntactical changes which lean in a similar direction.
The question is: does D (or whatever) excite you so much that you want to get in on the ground floor, as opposed to waiting a year or two? I actively don’t like C# (even if it wasn’t just another MS marketing gimmick), but I won’t complain if I’m eventually forced to use it.
What does D offer? I don’t want to give up auto class variables, particularly not for GC which I don’t really want anyway. I much prefer Objective-C’s retain/release/autorelease to GC: I implemented that in C++ but now I find I don’t use it very often.
Combining “.”, “->”, and “::” into “.” sounds cool, but I wouldn’t make much effort for it. It’s another way C++ makes you think about and understand what you’re doing.
The module concept is good, but it can be faked too, w/ a C++ code generator. I like that enough to make an extra effort when portable code or separate headers are needed.
D seems like YA wonder language whose tradeoff is ease of use vs quality of result. Not because C++ itself is better, but because it has a powerful Darwinian effect on its users (and as a survivor, I’m all in favor of that.)
>anytype func_any(anytype a)
>{
>
>if(typeof(a)==int)
>{
>//perform an integer operation
>b=new int[4];
>return b;
>}
>}
From your less-than-obvious-sample it is hard to tell what you´re actually trying to show.
If the type of your argument is set at compile-time, you´re best of with a template-function, if it is not set at compile-time and you´re using the anytype as a kind of variant/multi-type kind of type, it would be better if you´re code reflected that with a isString/isInt/isBla member function (Ugly, but possible). If you´re using typeof in the sense to act differently upon the type of anytype in the sense of polymorphism, then your sample shows nothing but bad design.
What is your sample supposed to show ?
Is this code you actually write ? Samples like that actually did make it into Stroustrups “C++ Programming Language” Book. Right into the “How not to do it”-section.
The omly appealing feature is the garbage collector … why not just add that to the next major C++ revision (Automatic, manual, off)
D looks great. I’ve never been a fan of bytecode based languages but at the same time I’ve never liked the complexities of C++. Instead I’ve fallen back on C (awful limitations compared to modern languages, eg lack of string and exception handling). I think I’ll give D a try, looks very appealing.
My question is this, does the language define the name-mangeling that compilers/linkers should use?
To me, this is the biggest pain in the arse with C++.
I enjoyed the article! I like the fact the D does not force OO on you when it is inappropriate.
The problem is that apparently an empty char array is equal to no array at all. This is clearly a Bad Thing(tm) since there is very much difference between ‘str=””;’ and ‘str=null;’.
str=””; means str is a pointer to a single byte containing 0.
str=null; means that str is not pointing to anything at all.
If you look at the compiled code, pointers have to be loaded into a register before they can be used. They often have to have arithmetic performed implicitly as well. During this time, a single check for a zero pointer would easily provide an early-out for the pointer operation. As long as the compiler writer keeps this in mind, using null pointers for empty arrays is BETTER than the alternative. In fact, since you are checking for null pointers as part of looking for empty arrays, you’ll automatically catch accidentally null pointers passed in by bad code. Therefore, it’s safer to use a null pointer as an empty array.
Walter’s original company was called Zortech not Zorland. Nobody remembers this good C compiler (and the company) from early 90s … Hmm, shame.
I’m sorry but PowerBuilder (PowerScript) is still the best high level language.
> it’s safer to use a null pointer as an empty array
Huh? I have no idea what you’re babbling about, but a null pointer and an empty string are two completely different things, just as a null pointer and the string “hello” are different. The fact that the length of the string “” is 0 doesn’t mean that it suddenly isn’t a string at all!
Let’s say I have a method for setting the password, setPassword(string newPassWord). Then consider this scenario:
| string newpw;
| switch (pwmode) {
| case 0: newpw=getNewPassWord(); break;
| case 1: newpw=readPassWord(stdin); break;
| }
| setPassword(newpw);
Now someone adds a new pwmode, 2, and so setPassword(null) will be called, but the setPassword method thinks this is an empty password (which are used for auto-logins) instead of throwing an InvalidNullArgumentException or similar.
This wasn’t a very good example, but I hope you get the point. The point was that there is a very clear distinction between en empty string and no string at all.
Go back and reread my comment. I clearly pointed out that a null pointer and a null string are different, and why null pointers as empty arrays can be considered good. Try to read the comments before responding.
This presentation has lots of information that explain the advantages of D, and the rationale of its features:
http://www.digitalmars.com/d/sdwest/index.html
To reply some of the objections to my post:
What I think of as a systemprogramming is a language usefull for operating systems, as in drivers and kernels, but also libraries both system- and application libraries.
Taking kernels first:
Yes, it is possible to write “kernels” in LISP, ML and concurrent pascal, but they are pointless exercises in computer science like compilers partially evaluated from an interpreter. Now get back to reality.
Turning off the garbage collecter or using one with real-time constaints is fine. The real problem is that the environment and requirements you have when writing a kernel, is widely different, not just from GUI programming but also from writing other types of kernels. I can hardly imagine circumstances where a kernel-programmer would _not_ write his own memory allocation. Yes, it could be GC, but it would likely not be a standard one.
As for libraries:
If the goal is to replace C as a library programming language, you have to write libraries that are somewhat language neutral and can be interfaced from many other languages. Now imagine writing a C-program and then calling a function in garbage-collected D-library…..
An empty set is still a set, not something that does not exist. Depending on how D handles this (I don’t know) it could be a major problem. You shouldn’t have to write special code to deal with the empty case.
>While C++ pioneered in generic programming
Does the author really believe that? I think Ada and Eiffel and several languages had them first. I don’t think Soustroup stressed them until the 2nd version of C++
Anybody want to clear up the history of C++ and generics/templates?
Yes, it is possible to write “kernels” in LISP, ML and concurrent pascal, but they are pointless exercises in computer science like compilers partially evaluated from an interpreter.
Why? This is what I meant when I talked about getting your head out of a certain place. Its really an asnine comment.
The real problem is that the environment and requirements you have when writing a kernel, is widely different, not just from GUI programming but also from writing other types of kernels. I can hardly imagine circumstances where a kernel-programmer would _not_ write his own memory allocation. Yes, it could be GC, but it would likely not be a standard one.
Memory allocation in a kernel is a pretty well-understood concept. The standard setup these days is a page manager, with a pool allocator layered on top, and a general purpose allocator for minor allocations. You’d probably want to write your own page allocator, but other than that, there isn’t anything really new to do. You could depend on the GC to provide the pool allocator, and GC all temporary memory. Such a system would work just great.
As far as I am aware, C++ was the first widely accepted language to use generics, and was definitely the first to make it a standard part of the programmer’s arsenal (provided that various C void* tricks aren’t really generic programming).
Yes, well. Since I wrote it in a text editor (ie. no spell/grammar check), I was hoping the OSNews editors would do a slightly more thorough job of proofreading. Now that I look back at it a few weeks later, some of the typos/grammar mistakes make my eyes burn!
I’m comparing the currently existing version of D to the currently existing versions of C# and Java. To do otherwise would be unfair. Certainly all three will be improving in the future (C# 2.0, Java 1.5, D 1.0), but those are irrelevant to a article comparing them NOW.
As I’ve tried to explain, there IS a difference between an empty string and a null value. Think of it like this:
In D, an array is basically a struct. It holds a pointer to the beginning of the array and a length property. Certainly this is an oversimplification, but it gets the point across.
In an empty string, the pointer to the beginning of the array is null. With a null value, there is no struct at all. Hence an empty array will still have a functional .length property that will read 0, allowing it to be differentiated from a null value which will throw an exception if you try to access .length, since nulls don’t have properties.
> In D, an array is basically a struct. It holds a pointer
> to the beginning of the array and a length property.
> Certainly this is an oversimplification, but it gets the
> point across.
>
> In an empty string, the pointer to the beginning of the
> array is null. With a null value, there is no struct at
> all. Hence an empty array will still have a functional
> .length property that will read 0, allowing it to be
> differentiated from a null value which will throw an
> exception if you try to access .length, since nulls
> don’t have properties.
Yes, here an empty string is not just null, but also the integer 0, and this is how it should be. If it really is like this in D then there is an error on http://www.digitalmars.com/d/cppstrings.html where it says “In D, an empty string is just null”.
> Go back and reread my comment.
I did reread it, several times. I’ve probably read it ten times already but I dimply don’t understand what you’re trying to get across. To me it seems like you’re discussing how to optimize zero length arrays, but that is completely irrelevant. I couldn’t care less about the low-level implementation of arrays. What I do want is that empty strings be different from null. Am I not making myself clear enough?
| a=””; b=null;
| if (a==b) {
| // this MUST NOT happen
| }
Do you agree?
“That’s not true. There IS a typeof operator in D. Please look at the last section of the Declarations section:
http://www.digitalmars.com/d/declaration.html“
Hey, that’s great!
Now we just need an ‘anytype’ type and we’ll (I’ll) be happy.
Peter
“What is your sample supposed to show ? ”
Dynamic allocation based on the type of a variable.
Actually, anything done dynamically based on the type
of a variable.
Pete
This should make my meaning more clear :
/************************************
EXAMPLE FUNCTION: func_any
this function is purely theoretical
and will not work in the context
of any current programming language.
The function demostrates a
programmatic action based on the data
type input to a function.
The current equivalent to ‘anytype’
is ‘void *’ but void * requires a
type cast to other pointer types.
ie:
typedef union __variable_pointer
{
void *pv;
int *pi;
char *pc;
unsigned short *pus;
float *pf;
double *pd;
}VARIABLE_POINTER;
typedef struct __a_variable
{
unsigned long var_type;
unsigned long size;
void *storage;
VARIABLE_POINTER data;
/* data.pv should always == A_VARIABLE.storage */
}A_VARIABLE;
************************************/
anytype func_any(anytype a)
{
anytype b;//this variable type is defined as it is created
if(typeof(a)==int)//a is int
{
b=new int[4];//allocate an int array
return b;//return the array
}
if(typeof(a)==char) // a is char
{
b=new char[4];//allocate a char array
return b;//return the array
}
switch(typeof(a))
{
case double: //a is double
b=new double[4];//allocate a double array
return b;//return the array
break;
case float://a is float
b=new float[4];//allocate a float array
return b;//return the array
break;
default:
return NULL;//possible undefined type
}/*end switch typeof(a)*/
} /* END func_any*/
pete
| a=””; b=null;
| if (a==b) {
| // this MUST NOT happen
| }
Do you agree?
Yep, I do agree. It doesn’t make any sense for need any if(){} braces if it’s going to be empty. It should be create something new like if(); or something better logic and clear to read. This above make something feel like it’s missing or unfinish.
I did reread it, several times. I’ve probably read it ten times already but I dimply don’t understand what you’re trying to get across. To me it seems like you’re discussing how to optimize zero length arrays, but that is completely irrelevant. I couldn’t care less about the low-level implementation of arrays. What I do want is that empty strings be different from null. Am I not making myself clear enough?
| a=””; b=null;
| if (a==b) {
| // this MUST NOT happen
| }
Do you agree?
Not necessarily. What is wrong with having the two be equivalent? As I said, since you are already loading the register to use the pointer and may also do arithmetic on it, it takes no extra time to check if it’s null and to treat it separately. This also has the added advantage of dealing with null pointers passed by bad code.
Say that a is not equal to b from your example above. Now someone passes in a or b set to null. This case must be handled using separate code or risk a dangling reference to unmapped memory. PC OSes usually use the MMU to pick up such cases via page faults. This is a necessary evil to catch sloppy programming.
It’s not an optimization so much as a method to also catch dangling pointers. Otherwise, you might need code like this:
if (!a || !b) {
// one string null!
}
> What is wrong with having the two be equivalent?
Uh.. because they are different? What is wrong with you? 2!=3, “a”!=”b”, “a”!=null and “”!=null. An empty string is NOT nothing, it is something, namely a string, just as the string “a” is a string. This is not something that can be negotiated, such as whether “a”==”a” or “a”!=”a” (i.e. they might be different objects but still equivalent). This is as clear as “a”!=2 and 42!=0.
> As I said, since you are already loading the register
Will you stop talking about irrelevant implementation details when I’m trying to discuss the language! Or is the point you’re trying to get across that you know that it’s wrong that “”==null, but that it is faster and therefore justified? If this is what you’re trying to say then fair enough, we disagree, I don’t think it’s justified, but let’s leave it at that. However, if this is not what you’re trying to say then you have to be clearer, because neither I nor anyone whose opinion I’ve asked about your writings have a clue what you’re trying to say.
> Say that a is not equal to b from your example above.
As is the case, yes.
> Now someone passes in a or b set to null.
Huh? Pass in where? It doesn’t matter what a and b is before that block of code since I very explicitly set a to “” and b to null on the very first line. Helloo-oo?
> This case must be handled using separate code or risk
> a dangling reference to unmapped memory.
What are you smoking, man?!? Which variable do you think would be a dangling reference to unmapped memory? ‘a’ is a pointer to a string object (be it a struct or whatever) and ‘b’ is a pointer to nothing. Besides, how on earth do you even think you could get a dangling reference at all in a fully GC’d language (unless you use arithmetics on pointers or mark that code as to be excluded from GC)?
D has a neat way of suppress garbage collection and even to allocate objects on the stack. Perfectly good for kernel programming. The choice of GC or not to GC, should not force you to change progamming languages.
The D language fails to innovate or be up to date where it could be:
Unimaginitive use of Unicode, it should use math operators like the single-character less-than-or-equals. Source code could be rich text.
Fixed-width fonts are artifacts of ancient history and should not be required for new programming languages.
Languages need better support for SQL data types (date/time) and the possibility of null fields.
There is no reason to keep the old-fashioned if statement. The if/else/elsif/endif format is widely used and understood and is easier to deal with. Single character graphics could be innovated to shorten the text. This requires some work on IDE’s.
Modern languages should assume IDE’s and should support IDE features like fill-in-the-blank coding.
The docs have great quote that made me smile:
“There’s no need for multiple warning levels in D, a “D Puzzle Book”, a lint program, a “Bug Of The Month”, or a world’s leading expert on preprocessor token concatenation”
The D language appears to be a proprietary invention of Walter Bright who is the sole arbiter of what gets in the language and the owner of the intellectual property. Although there is an OSS implementation.
Apparently there is no way to include the code for the Design-By-Contract in the release builds, but this could change.
> it should use math operators like the single-character
> less-than-or-equals
I disagree. You’d have to have non-standard keyboard mappings to support this.
> Fixed-width fonts are artifacts of ancient history and
> should not be required for new programming languages.
Well, unicode should be supported, but I don’t agree that all characters should be 24 or 32 bits. You might want to use UTF-8 if you don’t need to jump to the n:th character or if you’re short on memory. OTOH you might want to use UTF-32 if you need to jump to the n:th character a lot, or you might want to use UTF-8 and a jump table or something.
From the D language specs:
| char = unsigned 8 bit UTF-8
| wchar = unsigned 16 bit UTF-16
| dchar = unsigned 32 bit UTF-32
So what this mean in practice? I don’t know.
Anyway, I hope that the length of a string in D is the number of characters, and that there is some function/method to get the n:th character from a string.
> There is no reason to keep the old-fashioned if
> statement. The if/else/elsif/endif format is widely
> used and understood and is easier to deal with.
Are you saying that
| if (b1) {
| /*code*/
| } else if (b2) {
| /*code*/
| } else {
| /*code*/
| }
is harder to understand than
| if (b1)
| /*code*/
| elsif (b2)
| /*code*/
| else
| /*code*/
| endif”
and that it’s worth to have different kinds of blocks just because of this?
I disagree.
> Single character graphics could be innovated to shorten
> the text. This requires some work on IDE’s.
I disagree. As long as the code is text I think one should be able to type it using a standard keyboard. I really don’t want to memorize lots of keyboard shortcuts, nor do I want to spend lots of time moving my hand between the keyboard and the mouse.
Completely visual languages are a different matter.
There’s a lot to like in D. It’s the C and C++ that should have been. And if someone is starting out fresh and needed a C or C++ like language, then it would be a good choice.
For others, there’s probably too much inertia to overcome. People get set in their ways, and are blind to the faults in their language of choice.
I just wish that Walter Bright hadn’t given in to the idea that he could lure existing C/C++ coders. He rightly says that source-code compatibility is a non-starter if he wants to make a robust, viable language.
But he gave in to the look and feel in order to make D a familiar environment for C and C++ programmers and create a short learning curve. I think this was counter-productive. They aren’t coming over, and new programmers would be rightly put off by yet another curly brace language. Make a complete break! Banish curly braces and semi-colons to the ash-heap of dead languages. Not to mention parenthesized fors, whiles, switches, etc. How a language looks on the page has a lot to do with its productivity, lack of bugs, etc. Esthetics count.
Look at his sieve of Erastothenes sample program at the bottom of his introductory page with a fresh eye: http://www.digitalmars.com/d/index.html
Now how do those isolated curly braces contribute to your understanding? Are they for you, or for the compiler? They are just noise on the page. Next, some lines end in semi-colons, some don’t. How does that help your understanding? Not one whit.
(On the other hand, I think D is the only major compiled language I have seen that allows more than integer values in the SWITCH statement – not C, C++, JAVA, C#, ADA. Only the much maligned VB has a comparable feature in its SELECT statement.)
Anyone interested in this sort of thing should also check out Cyclone, “A Safe Dialect of C”, from Cornell and AT&T. I just wish language designers would drop the C-like syntax. Yuck yuck yuck!!!
http://www.cs.cornell.edu/projects/cyclone/
I wasn’t sure why “” should not be the same as null, but your post gave me the answer:
If I am inserting a varchar into a DB and I have a null pointer (empty string), what do I insert, “” or NULL? That is an important difference (unless you are using MySQL, that is).
Would a solution be that an empty string is not null but has zero length?
D lacks any real advantage of C++ or Java. Indeed, D takes a step back and fails to provide essentials like automatic memory management. You’d have to be living in a cave not to notice that all the “modern” languages (C#, Java, Ruby, Python etc.) all provide automatic memory management.
At the very least, D could have done something cool, like a CLOS-like object system, or blend functional, imperative and symbolic paradigms in a new, easy to use way. Maybe even incorporate AOP (aspect oriented programming) right into the language specification.
Instead, D provides us with yet another Algol 60 which will fail to get anywhere since its so similar to C and C++ that there’s no way for it to differentiate itself.
Very uncool.
> Would a solution be that an empty string is not null but
> has zero length?
That is the very definition of an empty string, so yes, it is indeed the correct “solution”. (There might be some incorrect solution that is better for some particular problem, though, e.g. you might want to replace the string “Foobar” with the integer 42 or something, but this is irrelevant.)
> D takes a step back and fails to provide essentials like
> automatic memory management
Huh? D is fully garbage collected. How does it not provide automatic memory management?
An empty string is NOT nothing, it is something, namely a string, just as the string “a” is a string. This is not something that can be negotiated
It COULD be nothing and CAN be negotiated. You’re just being pig-headed and opinionated. Try thinking outside the box for a change.
Will you stop talking about irrelevant implementation details when I’m trying to discuss the language! Or is the point you’re trying to get across that you know that it’s wrong that “”==null, but that it is faster and therefore justified?
It’s not irrelevant. Any language worth using must consider the implementation at some level or it will fall behind ones that do. Besides, this is a brand new language and can be changed however the folks setting the standards feel like. It’s not ANSI C. If they want to make “”=null, that’s their right. I was pointing out the fact that it can make nearly any implementation of the langauge better.
You’re arguing that because C defines a string one way that no other definition in any other language is acceptable. You’re wrong. It’s that simple.
> > An empty string is NOT nothing, it is something, namely
> > a string, just as the string “a” is a string. This is
> > not something that can be negotiated
>
> It COULD be nothing and CAN be negotiated.
Uh? No, a car is a car, a string is a string, an apple is an apple and null is null. A car is not null, an apple is not a string and a string is not null. What part of this is too hard for you to understand?
As I said, you might want to _TREAT_ a particular car as equivalent to the number 42 or a particular string as equivalent to null. This is clearly incorrect, but one might still want to do it in certain situations.
> You’re just being pig-headed and opinionated.
Yeah, right. And I suppose you also think that you aren’t. If there is something I’m guilty of then it’s that I’m feeding a troll like you.
> Try thinking outside the box for a change.
LOL!
How about you trying to think on a slightly higher level than registers and memory addresses? Do you think you could do that? D is not a macro assembler, you know.
> > Will you stop talking about irrelevant implementation
> > details when I’m trying to discuss the language! Or is
> > the point you’re trying to get across that you know
> > that it’s wrong that “”==null, but that it is faster
> > and therefore justified?
>
> It’s not irrelevant. Any language worth using must
> consider the implementation at some level or it will
> fall behind ones that do.
Of course the implementation is relevant, but your comments about the implementation have been irrelevant regarding the point I’ve been trying to make. I’ve only been talking from a programmer’s point of view, but your comments have been from a language implementer’s point of view (or something), and you’ve refused to listen to what I’m saying. As a programmer I don’t care how my languages are implemented, at least not as much as I care that they are easy and logical to use.
Also, you didn’t answer my question.
> I was pointing out the fact that it can make nearly any
> implementation of the langauge better.
That is not a fact and you know it, so just stop lying.
Sigh! Let me try once more to get even you to understand. If “argh”==42 then all programs that need to make a distinction between “argh” and 42 must implement ugly workarounds to get around what I would call bad design in the language. Do you agree? Now, how is the “”==null situation any different from the “argh”==42 situation?
> If they want to make “”=null, that’s their right.
Of course, and it’s my right to not like it.
> You’re arguing that because C defines a string one way
> that no other definition in any other language is
> acceptable.
What?!? Are you saying that “C” (whatever you mean by that) defines a string at all, and that I like, and even require, that definition? You are just unbelievable…
Try to snap out of your self-inflicted delusions for a moment now. I’m definitely not arguing that D should make a distinction between null and “” because of how any other language is or isn’t designed. Least of all would I want another C, which is a language that I simply hate, not least because of its lack of a decent string type. Please reread my previous postings.
> You’re wrong. It’s that simple.
ROTFL!
Not only have you not given any reason for why a programmer would want “”==null more often than not, but you also haven’t even tried to address my objections to it.
Basically, I never liked object oriented languages at all. Somehow it seems wrong to assume that everything is part of another, greater thing that is totally encapsulated and has to take care of itself. If the world was organized that way, a screw would either screw itself into the wall or came with its own screwdriver.
As a matter of fact, when you look under the hood of an object, all you see is a structure with a few pointers to functions. You don’t need an object oriented programming language to produce such code, C will do just fine, thank you very much.
BTW, structures are not very efficient. A structure gives usually rise to a frenzy of alignment problems that can only be solved by fillers. Actually, you really don’t need structures, since it can also be represented by a host of loosely related arrays. It doesn’t make much difference whether you write ‘row.column’ or ‘column [row]’, except that arrays of the same type are much easier to handle for both the compiler and the memory allocators.
Basically, there are only one-dimensional arrays or do you really believe that by magic memory is wrapped into matrices and cubes? The compiler conveniently translates your ‘array [x] [y]’ notations into real offsets like ‘array + ((x * size) + y)’.
There are a lot of fancy datatypes, but basically they are just arrays of arrays. As a matter of fact, there are only two real datatypes, a word and a byte. A pointer is usually a word. The different pointertypes are just created to let the compiler do some work for you, so you don’t have to remember what the real size of e.g. a character or an integer is. Thus, ‘char* p + 1’ can be translated into ‘p + sizeof (char)’.
I wonder why people need a ‘typeof()’ operator: after all these declarations in order to let the compiler do most of the work they seem to have forgotten halfway what type ‘p’ actually was. After all the help their object-oriented compiler gave them they have completely lost track of what they were doing. So, if it doesn’t help, what good is it?
As a matter of fact (hush!) there is no such thing as a pointer. It’s just an address, in other words: it is a variable that holds a location in memory. A NULL pointer is just a variable that points to the very first byte in memory (address 0) and by (compiler) convention that is not a valid address. A NULL string is a pointer to a byte in memory that just holds a terminator, which is 0 by convention. Note, these are just conventions. You could define another convention which may work just as well or even better.
Usually, I don’t need much more than a stack (where I push my parameters (all words)) and a way to allocate an array of words and bytes. When I push a byte on the stack, it is expanded to a word and when I store a value from the stack into a byte its ‘most significant bits’ are lost. When I’m done, I terminate the allocation. I don’t need a paranoid garbage collector to clean up my mess, thank you. Even less, I don’t need a compiler to do the ‘instantiation’ or ‘destruction’ of ‘objects’, I’m quite capable to allocate or deallocate a bunch of bytes or words myself.
BTW, the latter seems a lot easier. Not only that, but my programs seem to run a lot faster and are a lot smaller than most others. I can forgive D that it is OO. What the heck, I even forgave C that it was typed so I was forced to do some casts to get rid of those ugly warnings. It still seems odd I have to prove a dumb machine that I know what I am doing. The problem is that with C++ I have to figure out what he is doing by using ugly things like class browsers. Normally, I don’t even need a debugger, so why the heck should I use something as hideous as a class browser. When I’m really in trouble the assembly switch of a C compiler does wonders, even though most have forgotten
it’s in there.
But to get back to D: it seems to step out the way quite elegantly when needed and that’s all I ask. A compiler should be created humbly, not arrogantly. Why not: it’s there to help me; I forked out the bucks, so don’t bug me. If it never heard of a ‘byte class’ or a ‘word class’, it should follow some classes, not me. And don’t start to ask me for a ‘constructor method’: if I didn’t allocate it, I didn’t need it and you don’t have to ‘construct’ it for me.
In short, I’m not waiting for D. I’m still quite happy with C. However, it seems a better conceived language than C++ is. I can read it easily (without trying to remember what << or ++ means on Tuesdays) and it seems to realize very well that sometimes the world is not an object..
When these promises come true, I hope it will remain with us for a long time.
Uh? No, a car is a car, a string is a string, an apple is an apple and null is null. A car is not null, an apple is not a string and a string is not null. What part of this is too hard for you to understand?
You can’t seem to understand that the definition of objects in a language is just CONVENTION. There is NO REASON they cannot be redefined to something else. Or are you too ignorant to understand that?
Yeah, right. And I suppose you also think that you aren’t. If there is something I’m guilty of then it’s that I’m feeding a troll like you.
YOU are obviously the troll here.
How about you trying to think on a slightly higher level than registers and memory addresses? Do you think you could do that? D is not a macro assembler, you know.
Did you even READ the D specification and overview??? It says that part of its goal is to allow the programmer hardware level access and embedded assembly language. Now we are supposed to ignore the hardware and assembly language in a language DESIGNED to use them? You make less sense every post.
and you’ve refused to listen to what I’m saying. As a programmer I don’t care how my languages are implemented, at least not as much as I care that they are easy and logical to use.
Pot to kettle… hello… pot to kettle.
Also, you didn’t answer my question.
I answered it three times, but you’re too ignorant to understand the answer obviosuly.
That is not a fact and you know it, so just stop lying.
Trolling again… sigh. Go back to your BASIC class and maybe you’ll get a D.
Sigh! Let me try once more to get even you to understand. If “argh”==42 then all programs that need to make a distinction between “argh” and 42 must implement ugly workarounds to get around what I would call bad design in the language. Do you agree? Now, how is the “”==null situation any different from the “argh”==42 situation?
BIG SIGH!
Why should a language keep a bunch of pointers to bytes which are always 0? That’s all a null string is – a pointer to a byte set to 0 (in C). Why not set null strings to the same byte to save space? It won’t affect the programmer any. Why not set all null objects to the same pointer – a special code which means the object is empty… that would be even better and STILL not affect the programmer. Who CARES if “”=null as long as if (astr == “”) works properly? Like you said, it’s an implementation detail. So why the big fuss if someone wants to make it the same as null??
I like the idea that I could use if (!astr) to do the same thing as if (astr == “”).
Not only have you not given any reason for why a programmer would want “”==null more often than not, but you also haven’t even tried to address my objections to it.
I have given several reasons why a programmer would like it. You have yet to give a reason why not for me to refute other than state my definition is “illogical”.
> It says that part of its goal is to allow the programmer
> hardware level access and embedded assembly language.
Are you implying that low-level access and higher-level semantics are mutually exclusive? Get a clue!
This is the first sentence under the heading “Strings” in the D specs: “Languages should be good at handling strings.” I agree.
> Now we are supposed to ignore the hardware and assembly
> language in a language DESIGNED to use them?
I have said no such thing! You are putting words in my mouth.
> Why should a language keep a bunch of pointers to bytes
> which are always 0?
An empty string should NOT(!) be a pointer to a byte/word/whatever that is 0! This is what I’m trying to tell you.
From the D specs: “strings […] are not 0 terminated in D”
The pointer to the string data should of course be null for empty strings, but the pointer to the string should NOT. See a few paragraphs below if you’re too stupid to understand the difference between ‘string’ and ‘string data’.
> That’s all a null string is – a pointer to a byte set to
> 0 (in C).
Argh! There is no such thing as a “null string”! Either the thing it a string or it is null, it cannot be both. You just don’t make sense!
Also, a 0-terminated character array is just one particular implementation of a string. Modern programming languages really shouldn’t use such a naïve implementation because of its drawbacks.
> Why not set null strings to the same byte to save space?
Still not making sense. However, if you by “null strings” mean “empty strings” then sure, point them to the same empty string as long as you make sure that resizing one empty string doesn’t affect the other.
> Why not set all null objects to the same pointer – a
> special code which means the object is empty…
You are so confused. There is no such thing as a “null object”.
> Who CARES if “”=null as long as if (astr == “”) works
> properly?
I already wrote a program where it is cruicial that there be a distinction between an empty string and no string at all.
Let me make still another example. Let’s say I have a function like ‘setPassword(char[] newPassword)’. I want ‘setPassword(null)’ to mean ‘there is no password, and therefore there will be no password requester’. I want ‘setPassword(“argh”)’ to mean ‘there is a password, namely the string “argh”, and there will be a password requester’. Consistently I want ‘setPassword(“”)’ to mean ‘there is a password, namely the string “”, and there will be a password requester’. If “”==null then I’d have to add some other method or parameter to specify whether or not there is a password at all, and it would need a separate boolean variable, separate checks etc. It would work, but it’d be very ugly. I don’t want programming languages to enforce ugly implementations.
> Like you said, it’s an implementation detail. So why the
> big fuss if someone wants to make it the same as null??
I don’t make a big fuss about it, I just think it’s as stupid as it would be to make “argh”==42.
> You have yet to give a reason why not
Yes I have, and in this posting I have given you yet another one.
Let me quote a few things from the D specs before your stupidity overwhelms you completely.
In the “Strings” section we find this: “a string is just a dynamic array of characters”, and in the section about arrays we find this: “Dynamic arrays contain a length and a garbage collected pointer to the array data.” So an array is a pointer to a structure that has at least the attributes ‘length’ (an integer) and ‘data’ (a pointer, let’s ignore any memory manager structure that might be wrapping it), and possibly some type info or something. An empty string would therefore logically have ‘length=0’ and ‘data=null’. Now, what _I_ want is to be able to distinguish between a pointer to null and a pointer to an empty string, because of the reasons I’ve given.
hi
I has been reading the heat thread of Marcus Sundman vs. J.F.
and I have to say that both have some good points. please people clam down.
I had thougth a solution for having an array the way is seams to be inplemented in D that could handle both a null state and an empty state (I also think that there are times where you want to make them different and so not a satrange case at all). and the solution seams simple to me:
We only have to make by convention that if the data pointer is empty and the length is 0 the string is empty, but if the data pointer is empty and the length is not 0 (could be a convention like 0XFFFF or not) then the array is null.
> We only have to make by convention that if the data
> pointer is empty and the length is 0 the string is
> empty, but if the data pointer is empty and the length
> is not 0 (could be a convention like 0XFFFF or not)
> then the array is null.
There is no need for workarounds like that.
Consider ‘char[] a=null; char[] b=”ARGH”; char[] c=””;’. All of these are pointers:
– ‘a’ points to null
– ‘b’ points to a structure with the attributes ‘length=4’ and a pointer, ‘data’, to the four bytes ’65’, ’82’, ’71’ and ’72’
– ‘c’ points to a structure with the attributes ‘length=0’ and a pointer, ‘data’, to null
There is no need for workarounds like that.
Consider ‘char[] a=null; char[] b=”ARGH”; char[] c=””;’. All of these are pointers:
– ‘a’ points to null
– ‘b’ points to a structure with the attributes ‘length=4’ and a pointer, ‘data’, to the four bytes ’65’, ’82’, ’71’ and ’72’
– ‘c’ points to a structure with the attributes ‘length=0’ and a pointer, ‘data’, to null
I’ll go along with that. It’s sensible and won’t confuse anyone. I still think ‘c’ above pointing to a structure is extraneous, but it will simplify certain functions in that it can assume that a non-null pointer has a structure. If you added other attributes, it would also automatically handle that.
Your arguement about the whole sting thing is off because you are thinking in C. string a = null; doesn’t really work with strings in this language because strings aren’t pointers. I think it will treat it as a = null the same way as n = “”. Also a = “” doesn’t translate in to a[0]= ‘