www.digitalmars.com         C & C++   DMDScript  

D - D's documetation

reply Metthias Becker <Metthias_member pathlink.com> writes:
Don't get the folowing wrong. I just read through the whole D definition and
wrote down, what comes up to my mine. That's why it became pretty long. It's
intended to be a constructive critique. 

(quote)
The reality of the C++ compiler business is that few compilers effectively
implement the entire standard. 
(/quote)

That's true. The only compiler I know is Comeau, but there are many others like
gcc that come close enough to be usefull. And when it's true, what I've heard
about the new Borland compiler it seems we get another very close or even
perfect compiler.

(quote)
Can the power and capability of C++ be extracted, redesigned, and recast into a
language that is simple, orthogonal, and practical? Can it all be put into a
package that is easy for compiler writers to correctly implement, and which
enables compilers to efficiently generate aggressively optimized code? 
(/quote)

You don't answer the questions.
BTW: Is it realy possible to create something as powerfull as boost::lambda with
D? I don't know D very good, so I realy don't know, but I don't think so.


(quote)
The general look of D is like C and C++. This makes it easier to learn and port
code to D. Transitioning from C/C++ to D should feel natural, the programmer
will not have to learn an entirely new way of doing things. 
(/quote)

A C coder has to learn the objectorientated paradigm. So it's not easy to learn.
A C++ coder is used to have the powerfull STL and nowadays the Boost library,
but there is no pendant in D. So it doesn't feel natural for a C++ coder,
eigther.

E.g. a C++ coder want to copy the content of an container into a file he'd
write:

copy (container.begin(), container.end(), ostream_iterator<Type>(streamhandle,
delimiter));

You could use the same construct to copy a container into another one or to copy
a file to container, ... .

In D you have to do this totaly differently.

If you'd have to write prt<int> to create an int-pointer, it would still feel
natural to a c++ coder. It's the big things you got used to that matter, not
these small things.
You talk about the same look and feel. Let's take some C++-code and you sow me
how to port that while ceeping the same look and feel ( it's only a small part,
that's missing a lot of other headers ):

(c++ code)
template <
class methode_type_policy,
class check_policy = do_nothing_policy

class setgetter {
public: // Types
typedef typename methode_type_policy::value_type value_type;
typedef typename methode_type_policy::param_type param_type;
typedef typename methode_type_policy::return_type return_type;
typedef typename methode_type_policy::setter_type setter_type;
typedef typename methode_type_policy::getter_type getter_type;
typedef typename methode_type_policy::class_type * pointer;

public: // C'tors
explicit setgetter (pointer object=0, setter_type setter_methode=0, getter_type
getter_methode=0)
: m_this(object)
, m_setter(setter_methode)
, m_getter(getter_methode)
{ }

setgetter (const setgetter & other)
: m_this(other.m_this)
, m_setter(other.m_setter)
, m_getter(other.m_getter)
{ }

public: // Methodes
const setgetter & operator = (const setgetter & other)
{
m_this = other.m_this;
m_setter = other.m_setter;
m_getter = other.m_getter;
}

void operator = (param_type value)
{
check_policy::check(m_this);
check_policy::check(m_setter);

(m_this->*m_setter)(value);
}

operator return_type () const
{
check_policy::check(m_this);
check_policy::check(m_getter);

return (m_this->*m_getter)();
}


private:
pointer m_this;
setter_type m_setter;
getter_type m_getter;
};
(/c++ code)

Perhaps for a Java coder it feels "natural", but he/she will miss the reflection
ability.

(quote)
D programs can be written either in C style function-and-data or in C++ style
object-oriented, or any mix of the two. 
(/quote)
Well, C++'s oo-features a pretty limited. I'd expect more from a modern
programming language, but OK.


(quote)
Runtime Type Identification. This is partially implemented in C++; in D it is
taken to its next logical step. Fully supporting it enables better garbage
collection, better debugger support, more automated persistence, etc. 
(/quote)
Well, Java took it to the next logical step. You did something inbetween.


(quote)
Templates. Templates are a way to implement generic programming. Other ways
include using macros or having a variant data type. Using macros is out.
Variants are straightforward, but inefficient and lack type checking. The
difficulties with C++ templates are their complexity, they don't fit well into
the syntax of the language, all the various rules for conversions and
overloading fitted on top of it, etc. D offers a much simpler way of doing
templates. 
(/quote)

It's true that c++'s template syntax doesn't fit very well into the language. As
well it's true that macros are out. But I don't agree on the variant types. It's
true for stupid variants that some BASICs offer, but if you've ever coded in
Objective-C you'd know how powerfull and efficient variant types can be.



(quote)
Features To Drop
[...]
The C preprocessor. Macro processing is an easy way to extend a language, adding
in faux features that aren't really there (invisible to the symbolic debugger).
Conditional compilation, layered with #include text, macros, token
concatenation, etc., essentially forms not one language but two merged together
with no obvious distinction between them. Even worse (or perhaps for the best)
the C preprocessor is a very primitive macro language. It's time to step back,
look at what the preprocessor is used for, and design support for those
capabilities directly into the language. 
(/quote)
It's exactly, what I think. But then some of the Cuj-articles (www.cuj.com) come
to my mind and I doubt what I should think. There the preprocessor is used for
some realy tricky stuff. If you haven't read these articels you don't know, what
the preprocessor is realy used for. Perhaps you should read some of them and
than extend the language a bit so you realy can do the things you can with the
preprocessor without it.


(quote)
Namespaces. An attempt to deal with the problems resulting from linking together
independently developed pieces of code that have conflicting names. The idea of
modules is simpler and works much better. 
(/quote)
Both ideas can coexist perfectly. Namespaces are much more flexibel and let you
structure your code, while D's modules are there to prevent you from name
conflicts.


(quote)
Who D is For
[...]
Programmers who enjoy the expressive power of C++ but are frustrated by the need
to expend much effort explicitly managing memory and finding pointer bugs. 
(/quote)

All I can say is: smart pointers.
I still like a gc better.


(quote)
Programmers who enjoy the expressive power of C++ but are frustrated by the need
to expend much effort explicitly managing memory and finding pointer bugs. 
(/quote)

But C++'s power comes only from it's template abilitys. As D's abilitys
concerning that are realy limited you don't get C++'s power. How to do policy
based design in D? How to write as wildly usable code as the STL-algorithms? How
to create usefull tools like boost::bind, boost::lambda or boost::tuple? How to
write as general code as Alexandrescu's Loki (http://moderncppdesign.com)?


(quote)
There is no longer a need for a separate definition of member functions, static
members, externs, nor for clumsy syntaxes like: 
(/quote)

I totaly agree on static members and the extern stuff, but most languages point
their ability of seperating the interface from the implementation as a feature
not as a drawback. OK, C++'s way is realy clumsy, but other languages like
Objective-C does it realy convenient. 


(quote)
Associative Arrays
Associative arrays are arrays with an arbitrary data type as the index rather
than being limited to an integer index. In essence, associated arrays are hash
tables. Associative arrays make it easy to build fast, efficient, bug-free
symbol tables. 
(/quote)

Nothing to complain about that, but most C++ librarys ship with a collection of
different hashs. Normaly it's based on ehte Sgi-version ( www.sgi.com/tech/stl
). So you have hash-sets as well as hash-maps both in a multi-version, too (the
same key may occure more than once). Perhaps you should extend D's abilitys a
bit.
And there are other associative containers like trees, that aren't avilable for
D. But trees are rarly used, so it's not a that big drawback.


(quote)
Function Literals
Anonymous functions can be embedded directly into an expression. 
(/quote)

Normaly these things are cald lambda-expressions.


(quote)
Cast Expressions
In C and C++, cast expressions are of the form: 
(type) unaryexpression

There is an ambiguity in the grammar, however. Consider: 
(foo) - p;

Is this a cast of a dereference of negated p to type foo, or is it p being
subtracted from foo? This cannot be resolved without looking up foo in the
symbol table to see if it is a type or a variable. But D's design goal is to
have the syntax be context free - it needs to be able to parse the syntax
without reference to the symbol table. So, in order to distinguish a cast from a
parenthesized subexpression, a different syntax is necessary. 
C++ does this by introducing: 

dynamic_cast(expression)

which is ugly and clumsy to type. D introduces the cast keyword: 
cast(foo) -p;	cast (-p) to type foo
(foo) - p;	subtract p from foo

cast has the nice characteristic that it is easy to do a textual search for it,
and takes some of the burden off of the relentlessly overloaded () operator. 
(/quote)

In C++ there is a static_cast<Type>(expression), const_cast<Type>(expression),
reinterpret_cast<Type>(expression) and the already mentioned
dynamic_cast<Type>(expression). Today nobody uses the C-casts any longer. 
static_cast<foo>(-p) isn't ambingious.

And casts are clumsy, because you normaly shouldn't cast and the clumsy syntax
protects you from casting more than needed.


(quote)
A block statement introduces a new scope for local symbols. A local symbol's
name, however, must be unique within the function. 
(/quote)

Why?

So

for (int i=0; i<10; ++i)
foo;

for (int i=0; i<10; ++i)
bar;

is illegal? What about your sentence "Transitioning from C/C++ to D should feel
natural, the programmer will not have to learn an entirely new way of doing
things."?


Why are reverse and sort abilitys of arrays? shouldn't they be part of the
library? Or is it realy much more efficient this way?


(quote)
Resizing a dynamic array is a relatively expensive operation. So, while the
following method of filling an array: 
[... some code]	
will work, it will be efficient
(/quote)

You mean it wont, not it will, don't you?


(quote)
str ~= "\0";
printf("the string is '%s'\n", (char *)str);
(/quote)

(char *) looks like a C-style cast. What is it?


(quote)
Enums replace the usual C use of #define macros to define constants. Enums can
be either anonymous, in which case they simply define integral constants, or
they can be named, in which case they introduce a new type. 
(/quote)

Hu??? enum seems to be the same as enum in C and in C you'd use enum. So this is
stupid.


(quote)
In C++, there are many complex levels of function overloading, with some defined
as "better" matches than others. If the code designer takes advantage of the
more subtle behaviors of overload function selection, the code can become
difficult to maintain. Not only will it take a C++ expert to understand why one
function is selected over another, but different C++ compilers can implement
this tricky feature differently, producing subtly disastrous results. 

In D, function overloading is simple. It matches exactly, it matches with
implicit conversions, or it does not match. If there is more than one match, it
is an error. 
(/quote)

While this is good in general there might be some places, where this can be a
disadventage. E.g Alexandrescu's Mojo (you can find a description in one of the
Cuj articles).
But I don't think this is a reason to change this. I just wanted to mention it.

(quote)
Parameters are in, out, or inout. in is the default; out and inout work like
storage classes. For example: 
(/quote)

But why is there a keyword in? Isn't it more complicated for the compiler,
because it has to dispatch, whether it is the in-operator or the in-modifier? I
think there is no need for in in this case.



Hu? What's up with the folowing:
(quote)
It is an error to declare a local variable that hides another local variable in
the same function: 

void func(int x)
{   int x;		error, hides previous definition of x
double y;
..
{   char y;	error, hides previous definition of y
int z;
}
{   wchar z;	legal, previous z is out of scope
}
}

(/quote)

but before:
(quote)
void func3()
{
{	int x;
}
{	int x;	// illegal, x is multiply defined in function scope
}
}
(/quote)

Sorry, but I don't understand that.



D's templates seem to be very complicated and somewhat limited compared to C++'s
templates.

(c++ code)
template <typename T>
void foo (T bar)
{ ... }

double quer ()
{ ... }


foo(quer());  // the work is done by the compiler
(/c++ code)

versus

(D code)
template my_template (T) {
void foo (T bar)
{ ... }
}

double quer ()
{ ... }

instance my_template(double) my_instance;
my_instance.foo(quer);
(/D code)

If I got it right. Perhaps you should think about a way making it more easy.


About user defined memory allocation:
(quote)
- If new() cannot allocate memory, it must not return null, but must throw an
exception. 
[...]
- A null is not returned if storage cannot be allocated. Instead, an exception
is thrown.
(/quote)
Where is the difference between these two points?




About Phobos' conv

Just an idea, but perhaps this should become a mupltiply specialised template.
If D's template abilitys weren't that limited, I'd suggest something like
boost::lexical_cast

(c++ code)
using namepsace std;
using namepsace boost;

string my_string = "123";

int foo = lexical_cast<int>(my_string);

string bar = lexical_cast<string>(foo);
(/c++ code)


About Phobos' instrinsic

why aren't the math functions instrinsic if possible and are removed in this
part ot Phobos.


About Phobos' string
There are some functions like find, replace, insert or count, that you normaly
want to apply on all types of array, not only on char-arrays. Why are they that
limited?



From the FAQ:
(quote)
Why is [expletive deleted] printf in D?
printf is not typesafe. It's old fashioned. It's not object-oriented. It's not
usable with user-defined types. printf is guilty as charged. But it's just so
darned useful. Nothing beats it for banging out a quick dump of a value when
debugging. 
(/quote)
Look at boost::format. It's typesafe, can be used with userdefined types, but
uses a printf-like formatstring. OK, you can't do this in D, because of the
limited templates, but if templates might be reviewed it might be an interesting
option.

(quote)
Why fall through on switch statements?
Many people have asked for a requirement that there be a break between cases in
a switch statement, that C's behavior of silently falling through is the cause
of many bugs. 
The reason D doesn't change this is for the same reason that integral promotion
rules and operator precedence rules were kept the same - to make code that looks
the same as in C operate the same. If it had subtly different semantics, it will
cause frustratingly subtle bugs. 
(/quote)


is no silent fall through. The last command before a case statement must be
eigther break, return or goto. With goto you can simulate the fall through.

(pseudocode)
switch (foo) {
case 'a':
goto case 'A';

case 'A':
do_something();
break;

case 'b':
goto case 'B';

case 'B':
return bar;

default:
something_else();
}
(/pseudocode)



(quote)
Doesn't C++ support strings, bit arrays, etc. with STL?
In the C++ standard library are mechanisms for doing strings, bit arrays,
dynamic arrays, associative arrays, bounds checked arrays, and complex numbers. 
Sure, all this stuff can be done with libraries, following certain coding
disciplines, etc. But you can also do object oriented programming in C (I've
seen it done). Isn't it incongruous that something like strings, supported by
the simplest BASIC interpreter, requires a very large and complicated
infrastructure to support? Just the implementation of a string type in STL is
over two thousand lines of code, using every advanced feature of templates. How
much confidence can you have that this is all working correctly, how do you fix
it if it is not, what do you do with the notoriously inscrutable error messages
when there's an error using it, how can you be sure you are using it correctly
(so there are no memory leaks, etc.)? 

D's implementation of strings is simple and straightforward. There's little
doubt how to use it, no worries about memory leaks, error messages are to the
point, and it isn't hard to see if it is working as expected or not. 
(/quote)

This is only a paritial answer. You only anwer the string-part and you forget
that STL-strings are much more flexible, becuase they accept user defined
policys. OK in general case you don't need them, but than you can use the
typedef std::string instead of std::basic_string.

And how can I know, that the D compiler I use is perfect? I have to hope it
does, as I have to hope that my STL-implementation does. And if my
STL-implementation has a bug I could fix it myself until there is a official
bugfix, but what about a broken compiler?

And sorry, but the STL is just much more flexible than D's datastructures are.
In D I have dynamic array and one type of hash. The STL has a dynamic array, a
double linked list, something inbetween called double ended quque, four types of
trees, and almoast all implementations have four additional
hash-implementations. And than there are adapters like a stack, a quque and a
priority quque. SGi's implementation (that is wildly used, STLport is based on
it) additionaly has a singly linked list.
These are all datastructures I use in everydays business. They aren't something
extraordinary.

And who cares about how many lines the sting implementations has. Maybe you've
written 5000 lines in you D-compiler for it. Who knows? And who is realy
interested in it?

You can say everything about C++, it has a ugly, clumsy syntax or whatever, but
the STL is the best library for these proposes, ever.


(quote)
Can't unit testing be done in C++ with an add-on library?
Sure. Try one out and then compare it with how D does it. It'll be quickly
obvious what an improvement building it into the language is. 
(/quote)
Are there realy people that asked this? I think it is pretty obvious that the
build in tests have big adventages. That is one of the things I realy like in D.
That's why I thought about switching to D, but I'd miss the STL, many of the
boost-features and the MUCH more powerfull templates too much.



-> Example: wc

Why do you change your style all the time? 
In the first for-loop use write c++-coder-like ++i in the second one you write
j++ like a coder of another language would do.
Sometimes you leave lines beginning with { free, sometimes you declare variables
in them.
Sometimes you directly initialice variables somtimes you split it up into two
lines:
char[] word = input[wstart .. input.length];
but
char[] word;
word = keys[i];

This is realy strange code. It looks like it was written by two totaly different
coders. Perhaps you should review your code.
Some small changes like the following code would be enough to give it a general
look and feel (while that is still far away from how I'd do it):

(D code)
import stdio;
import file;

int main (char[][] args)
{
int w_total;
int l_total;
int c_total;
int[char[]] dictionary;

printf("   lines   words   bytes file\n");
for (int i = 1; i < args.length; ++i)
{
int w_cnt, l_cnt, c_cnt;
int inword;
int wstart;

char[] input = File.read(args[i]);

for (int j = 0; j < input.length; ++j)
{   
char 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[] word = input[wstart .. input.length];
++dictionary[word];
}
printf("%8lu%8lu%8lu %s\n", l_cnt, w_cnt, c_cnt, (char *)args[i]);
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");
char[][] keys = dictionary.keys;
for (int i = 0; i < keys.length; i++)
{	
char[] word = keys[i];
printf("%3d %.*s\n", dictionary[word], word);
}
return 0;
}

(/D code)



Finaly I'd like to say that D is missing the realy new things. If you like
design by contract, you could switch to Eiffel or Sather, which both have in
addition a much more convenient notation of generic code (templates). Translated
to D it would be something like:

(pseudocode)

class My_class [T] {
T foo;
T bar (T value)
{ ... }
}

..

My_Class[int] my_instance;
My_Class[double] another_instance;
(/pseudocode)

This would perfectly fit into D as D's hashes use the same syntax. And you could
implement it this way: You only create one type of My_class using Object for
template-parameters. The explicit type is only used by the compiler to
implicitly insert casts where needed. This way you don't waste any memory, and
everything is typesafe.

To get back to the topic: D isn't as flexible as Objective-C or Samlltalk, it
isn't as portable as Java, it isn't as powerfull as C++, it doesn't have a big

for small automizations D is too complex, so you'd prefer a scriptlanguage like
Phyton or Ruby. So I don't see where to use D.
Nov 02 2003
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Comments embedded.

Metthias Becker wrote:
 (quote)
 Can the power and capability of C++ be extracted, redesigned, and recast into a
 language that is simple, orthogonal, and practical? Can it all be put into a
 package that is easy for compiler writers to correctly implement, and which
 enables compilers to efficiently generate aggressively optimized code? 
 (/quote)
 
 You don't answer the questions.
 BTW: Is it realy possible to create something as powerfull as boost::lambda
with
 D? I don't know D very good, so I realy don't know, but I don't think so.
D is an attempt to answer those questions. And no, D doesn't have C++'s metaprogramming capacity.
 (quote)
 The general look of D is like C and C++. This makes it easier to learn and port
 code to D. Transitioning from C/C++ to D should feel natural, the programmer
 will not have to learn an entirely new way of doing things. 
 (/quote)
 
 A C coder has to learn the objectorientated paradigm. So it's not easy to
learn.
 A C++ coder is used to have the powerfull STL and nowadays the Boost library,
 but there is no pendant in D. So it doesn't feel natural for a C++ coder,
 eigther.
Not really. D doesn't require objects for anything. The standard library uses them here and there, but it's not like you need to be a rocket scientist to understand how those classes work. This isn't java; you don't need two decorator classes just to read a line of text from stdin. :)
 E.g. a C++ coder want to copy the content of an container into a file he'd
 write:
 
 copy (container.begin(), container.end(), ostream_iterator<Type>(streamhandle,
 delimiter));
 
 You could use the same construct to copy a container into another one or to
copy
 a file to container, ... .
 
 In D you have to do this totaly differently.
foreach (Element iter; container) { file.write(iter); file.write(delimiter); } It's not too bad. :)
 If you'd have to write prt<int> to create an int-pointer, it would still feel
 natural to a c++ coder. It's the big things you got used to that matter, not
 these small things.
 You talk about the same look and feel. Let's take some C++-code and you sow me
 how to port that while ceeping the same look and feel ( it's only a small part,
 that's missing a lot of other headers ):
 
 [...]
You don't need to write anything at all. D has properties (get/setters) as part of the language. Invariants and pre/postconditions can cover the type checking policy. Mega-template heavy metaprogramming isn't easily done in D at all, I readily concede. But it isn't needed nearly as much. It's a tradeoff. Lastly, I don't think that sort of C++ is the least bit natural. :)
 (quote)
 Templates. Templates are a way to implement generic programming. Other ways
 include using macros or having a variant data type. Using macros is out.
 Variants are straightforward, but inefficient and lack type checking. The
 difficulties with C++ templates are their complexity, they don't fit well into
 the syntax of the language, all the various rules for conversions and
 overloading fitted on top of it, etc. D offers a much simpler way of doing
 templates. 
 (/quote)
 
 It's true that c++'s template syntax doesn't fit very well into the language.
As
 well it's true that macros are out. But I don't agree on the variant types.
It's
 true for stupid variants that some BASICs offer, but if you've ever coded in
 Objective-C you'd know how powerfull and efficient variant types can be.
 
 
 
 (quote)
 There is no longer a need for a separate definition of member functions, static
 members, externs, nor for clumsy syntaxes like: 
 (/quote)
 
 I totaly agree on static members and the extern stuff, but most languages point
 their ability of seperating the interface from the implementation as a feature
 not as a drawback. OK, C++'s way is realy clumsy, but other languages like
 Objective-C does it realy convenient. 
It's a feature, not a bug! :) If you want to separate interface from implementation, then code an interface, and put it in another source file.
 (quote)
 Cast Expressions
 In C and C++, cast expressions are of the form: 
 (type) unaryexpression
 
 There is an ambiguity in the grammar, however. Consider: 
 (foo) - p;
 
 Is this a cast of a dereference of negated p to type foo, or is it p being
 subtracted from foo? This cannot be resolved without looking up foo in the
 symbol table to see if it is a type or a variable. But D's design goal is to
 have the syntax be context free - it needs to be able to parse the syntax
 without reference to the symbol table. So, in order to distinguish a cast from
a
 parenthesized subexpression, a different syntax is necessary. 
 C++ does this by introducing: 
 
 dynamic_cast(expression)
 
 which is ugly and clumsy to type. D introduces the cast keyword: 
 cast(foo) -p;	cast (-p) to type foo
 (foo) - p;	subtract p from foo
 
 cast has the nice characteristic that it is easy to do a textual search for it,
 and takes some of the burden off of the relentlessly overloaded () operator. 
 (/quote)
 
 In C++ there is a static_cast<Type>(expression), const_cast<Type>(expression),
 reinterpret_cast<Type>(expression) and the already mentioned
 dynamic_cast<Type>(expression). Today nobody uses the C-casts any longer. 
 static_cast<foo>(-p) isn't ambingious.
 
 And casts are clumsy, because you normaly shouldn't cast and the clumsy syntax
 protects you from casting more than needed.
D just has one cast keyword, and it's shorter. The type of cast is implicit; all class -> class casts behave like dynamic_cast. int->void* casts behave like reinterpret_cast, and so forth.
 (quote)
 A block statement introduces a new scope for local symbols. A local symbol's
 name, however, must be unique within the function. 
 (/quote)
 
 Why?
 
 So
 
 for (int i=0; i<10; ++i)
 foo;
 
 for (int i=0; i<10; ++i)
 bar;
 
 is illegal? What about your sentence "Transitioning from C/C++ to D should feel
 natural, the programmer will not have to learn an entirely new way of doing
 things."?
It's perfectly legal. Hiding an 'outer' local variable in a nested block is not. void foo() { int i; { int i; // not allowed, we already have an i int j; } { int j; // allowed, the previous j is out of scope } }
 (quote)
 str ~= "\0";
 printf("the string is '%s'\n", (char *)str);
 (/quote)
 
 (char *) looks like a C-style cast. What is it?
It is. D still has those. (regrettably, might I add) It's just different syntax for the exact same semantic.
 (quote)
 Enums replace the usual C use of #define macros to define constants. Enums can
 be either anonymous, in which case they simply define integral constants, or
 they can be named, in which case they introduce a new type. 
 (/quote)
 
 Hu??? enum seems to be the same as enum in C and in C you'd use enum. So this
is
 stupid.
I think the D spec predates C99. And, correct me if I'm wrong, but C had no enums until C99.
 D's templates seem to be very complicated and somewhat limited compared to
C++'s
 templates.
 
 (c++ code)
 template <typename T>
 void foo (T bar)
 { ... }
 
 double quer ()
 { ... }
 
 
 foo(quer());  // the work is done by the compiler
 (/c++ code)
 
 versus
 
 (D code)
 template my_template (T) {
 void foo (T bar)
 { ... }
 }
 
 double quer ()
 { ... }
 
 instance my_template(double) my_instance;
 my_instance.foo(quer);
 (/D code)
 
 If I got it right. Perhaps you should think about a way making it more easy.
Yes. The trouble lies in finding a compromise that will work well, without causing people to pull their hair out trying to implement it right.
 About Phobos' instrinsic
 
 why aren't the math functions instrinsic if possible and are removed in this
 part ot Phobos.
Intrinsic functions aren't functions at all, as I understand it. They translate directly to assembly instructions. If there's no assembly instruction to do some math operation, then you won't find an intrinsic for it. :)
 About Phobos' string
 There are some functions like find, replace, insert or count, that you normaly
 want to apply on all types of array, not only on char-arrays. Why are they that
 limited?
More D template woes. ;)
 Look at boost::format. It's typesafe, can be used with userdefined types, but
 uses a printf-like formatstring. OK, you can't do this in D, because of the
 limited templates, but if templates might be reviewed it might be an
interesting
 option.
I've done this in D without templates. It works pretty nicely.
 And sorry, but the STL is just much more flexible than D's datastructures are.
 In D I have dynamic array and one type of hash. The STL has a dynamic array, a
 double linked list, something inbetween called double ended quque, four types
of
 trees, and almoast all implementations have four additional
 hash-implementations. And than there are adapters like a stack, a quque and a
 priority quque. SGi's implementation (that is wildly used, STLport is based on
 it) additionaly has a singly linked list.
 These are all datastructures I use in everydays business. They aren't something
 extraordinary.
 
 And who cares about how many lines the sting implementations has. Maybe you've
 written 5000 lines in you D-compiler for it. Who knows? And who is realy
 interested in it?
 
 You can say everything about C++, it has a ugly, clumsy syntax or whatever, but
 the STL is the best library for these proposes, ever.
Except that the error messages STL gives you are TERRIBLE. ;) And the resulting code can be exceptionally cryptic.
 (quote)
 Can't unit testing be done in C++ with an add-on library?
 Sure. Try one out and then compare it with how D does it. It'll be quickly
 obvious what an improvement building it into the language is. 
 (/quote)
 Are there realy people that asked this? I think it is pretty obvious that the
 build in tests have big adventages. That is one of the things I realy like in
D.
 That's why I thought about switching to D, but I'd miss the STL, many of the
 boost-features and the MUCH more powerfull templates too much.
Yes. Need to hassle Walter about templates more. Oddly, though, I don't miss them as much as I thought I would when using D. They're not as important, I guess.
 To get back to the topic: D isn't as flexible as Objective-C or Samlltalk, it
 isn't as portable as Java, it isn't as powerfull as C++, it doesn't have a big

 for small automizations D is too complex, so you'd prefer a scriptlanguage like
 Phyton or Ruby. So I don't see where to use D.
D tries to capture 90% of what C++ can do, and put it in a nicer package. It's clear that you are very much a fan of that last 10%. :) -- andy
Nov 02 2003
parent Charles Hixson <charleshixsn earthlink.net> writes:
Andy Friesen wrote:
 
 ...
 D tries to capture 90% of what C++ can do, and put it in a nicer 
 package.  It's clear that you are very much a fan of that last 10%. :)
 
  -- andy
 
But I do wish that D had taken more of it's templating specs from Eiffel. This is one of the things that I believe Eiffel got correct. (Also I like Eiffel's handling of multiple inheritance, but interfaces are a livable solution that's easy on the implementor.) But Eiffel's "Generic" parameters are nearly optimal. They do, however, require that the compiler consider EVERYTHING an object, and consider that non-objects, like, say, integers, are compile time optimizations.
Nov 02 2003
prev sibling parent "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> writes:
 Are there realy people that asked this? I think it is pretty obvious that
the
 build in tests have big adventages. That is one of the things I realy like
in D.
 That's why I thought about switching to D, but I'd miss the STL, many of
the
 boost-features and the MUCH more powerfull templates too much.
Matthias We're are very hopeful that there will be a template library that will actually be better than the STL. I've said to Walter that (IMO) without such a thing, D will not succeed. When we get into it (next year, probably), there'll be some *big* changes to the language in order to support a superb templates implementation, and Walter's preparing himself for that (I think he's going to have to eat a lot of Christmas pudding to build up his strength. It is people like yourself, who have strong opinions on the STL, who are needed, so I'd urge you to stick around. :) -- Matthew Wilson STLSoft moderator and C++ monomaniac (http://www.stlsoft.org) Contributing editor, C/C++ Users Journal (www.synesis.com.au/articles.html#columns) "An Englishman by birth, a Yorkshireman by the grace of God" -- Michael Gibbs ---------------------------------------------------------------------------- ---
Nov 02 2003