Hello D community! :-)
I was looking for a sane, object-oriented,
possible-to-go-low-level programming language, so I decided to
give D a try today.
Here's some feedback on the things I had/have trouble with. I
hope some of this may be valuable for you.
1) First off, I really couldn't figure out were I was supposed to
post this sort of message. Apparently there aren't any mailing
lists (a la Google groups) for D?
2) I couldn't find any good documentation on the build process
and tools I'm supposed to use. Do you guys use standard
Makefiles? Do you have your own build system? Would be really
helpful if that was covered on the website.
3) While your error messages are a lot better than GCCs (gives
you more context, hints about how the compiler interpreted your
buggy program, etc) it wouldn't hurt if you made them a bit more
graphical using colors and markers and such (LLVM like).
4) What's the difference between `... foo(MyObject obj) { ... }`
and `foo(MyObject* obj)`? What are use cases for explicit
pointers when passing objects? That's not covered in the
documentation AFAIT.
5) What's wrong with this program? Is it that `printf` doesn't
understand D strings? If so, how do I use D strings in string
formatting?
import std.stdio;
string foo() { return "foobar"; }
int main() {
printf("%s\n", foo());
return 0;
}
Jonas

I don't think the compiler can warn about this. Isn't printf one of
those unsafe C variadic functions? Someone correct me if I'm wrong.

The GCC C compiler proves you wrong :) They have warnings. I guess it's
a hack (because printf really doesn't belong into the compiler) but that
doesn't matter. What matters is user-friendliness.

Indeed. dmd should warn about any incompatible data passed as variadic
parameters. It's simple to decide: only fundamental types that
correspond to C counterparts should be allowed. Hmmm... Even that's not
that simple: int is 32 bits in D but unspecified in C.
Ali

The GCC C compiler proves you wrong :) They have warnings. I
guess it's
a hack (because printf really doesn't belong into the
compiler) but that
doesn't matter. What matters is user-friendliness.

Indeed. dmd should warn about any incompatible data passed as
variadic parameters. It's simple to decide: only fundamental
types that correspond to C counterparts should be allowed.
Hmmm... Even that's not that simple: int is 32 bits in D but
unspecified in C.

Maybe printf should not be visible at all - or under a different
name ("cprintf" or something similar). It's just too tempting...
C variadic arguments are one of the most unsafe features of the C
language. A total mess.
Stefan

I don't think the compiler can warn about this. Isn't printf one of
those unsafe C variadic functions? Someone correct me if I'm wrong.

It is, but arguably this is exactly why it should warn - it's unlikely
that passing a D array to an extern(C) variadic function is really what
the programmer intended. Except of course when he relies on the internal
D array representation - and, as this hack is given as an example on
dlang.org, issuing a warning is out of the question, w/o special-casing
for printf and parsing the format string...
However, there's no reason why *std.stdio* should expose the raw printf
function - i didn't even realize it did until now...
It either shouldn't be available via std.stdio at all, or something
like this wrapper should be added there, to catch the inevitable mistakes:
int printf(string F=__FILE__, int L=__LINE__, A...)(A args) {
import std.typetuple;
import std.string;
import std.c.stdio;
alias ReplaceAll!(immutable(char)[], char*, A) CA;
CA cargs;
foreach (i, arg; args) {
static if (is(typeof(arg):const(char)[])) {
pragma(msg, F ~ ":" ~ L.stringof ~
" Warning: C function printf expects zero-terminated (char*), not D
array");
cargs[i] = cast(char*)toStringz(arg);
}
else
cargs[i] = arg;
}
return std.c.stdio.printf(cargs);
}
The raw printf can then still be used via std.c.stdio or core.stdc.stdio,
but a program using just std.stdio will print a warning instead of segfaulting.
Parsing the format string to avoid the warnings for the "%.*s" case could be
done too, i guess.
On 04/09/12 17:50, Jonas H. wrote:

The GCC C compiler proves you wrong :) They have warnings. I guess it's a hack
(because printf really doesn't belong into the compiler) but that doesn't
matter. What matters is user-friendliness.

D doesn't even need compiler support for this - it can be done completely
inside the library.
artur

However, there's no reason why *std.stdio* should expose the raw printf
function - i didn't even realize it did until now...
It either shouldn't be available via std.stdio at all, or something
like this wrapper should be added there, to catch the inevitable mistakes:

I think most mentions of printf should just be removed from the dpl
docs except maybe a few special places. People (or rather C++
refugees) seem to expect D to be a syntax sugared version of C++, but
this myth has to be busted.

I think most mentions of printf should just be removed from the dpl
docs except maybe a few special places. People (or rather C++
refugees) seem to expect D to be a syntax sugared version of C++, but
this myth has to be busted.

I don't think that's true, or at least I didn't think of D like that.
It becomes pretty clear after reading the introduction that D does not
try to emulate C++, let alone be compatible to C(++).
Nevertheless, because the syntax and terminology are quite similar,
people expect stuff to have the same names. That's why I expected the
standard printing function to be named `printf` and this attempt failed
miserably, without any guidance from the compiler/stdlib/whatever.

I was looking for a sane, object-oriented,
possible-to-go-low-level programming language, so I decided to
give D a try today.

D supports OOP well enough, but template-based programming seems
equally fit or even more. Also keep in mind that the D GC is not
so efficient, so avoid creating too many small objects, as you do
in Java.

1) First off, I really couldn't figure out were I was supposed
to post this sort of message.

This is the right place.

2) I couldn't find any good documentation on the build process
and tools I'm supposed to use. Do you guys use standard
Makefiles? Do you have your own build system? Would be really
helpful if that was covered on the website.

One tool fit for not huge programs is rdmd. I use "bud" still,
but it's getting obsolete.

3) While your error messages are a lot better than GCCs (gives
you more context, hints about how the compiler interpreted your
buggy program, etc) it wouldn't hurt if you made them a bit
more graphical using colors and markers and such (LLVM like).

If obj is a class instance, then the first syntax is the one you
will find in D programs.

What are use cases for explicit pointers when passing objects?
That's not covered in the documentation AFAIT.

It's not documented because you don't use explicit pointers to
pass objects around. Pointers are used to pass structs around
when you don't want to copy them.

5) What's wrong with this program? Is it that `printf` doesn't
understand D strings? If so, how do I use D strings in string
formatting?

Use write, writef, writeln, writefln for D strings and for
several other D data structures.
Take a look here for many small examples programs in D to do many
different kind of things (not all of them are up to date or fully
correct, but most of them are good, and the wrong ones are being
fixed one after the other):
http://rosettacode.org/wiki/Category:D
Bye,
bearophile

I was looking for a sane, object-oriented,
possible-to-go-low-level programming language, so I decided to
give D a try today.

D supports OOP well enough, but template-based programming
seems equally fit or even more. Also keep in mind that the D GC
is not so efficient, so avoid creating too many small objects,
as you do in Java.

1) First off, I really couldn't figure out were I was supposed
to post this sort of message.

This is the right place.

2) I couldn't find any good documentation on the build process
and tools I'm supposed to use. Do you guys use standard
Makefiles? Do you have your own build system? Would be really
helpful if that was covered on the website.

One tool fit for not huge programs is rdmd. I use "bud" still,
but it's getting obsolete.

3) While your error messages are a lot better than GCCs (gives
you more context, hints about how the compiler interpreted
your buggy program, etc) it wouldn't hurt if you made them a
bit more graphical using colors and markers and such (LLVM
like).

I don't think Walter will love this idea.

Could you please elaborate on this a bit more? What's the problem
with helpful compiler messages?

What are use cases for explicit pointers when passing objects?
That's not covered in the documentation AFAIT.

It's not documented because you don't use explicit pointers to
pass objects around. Pointers are used to pass structs around
when you don't want to copy them.

Thanks for the explanation!

Take a look here for many small examples programs in D to do
many different kind of things (not all of them are up to date
or fully correct, but most of them are good, and the wrong ones
are being fixed one after the other):
http://rosettacode.org/wiki/Category:D

That looks great, thanks, although it's a bit cluttered with all
those languages ;-)

Could you please elaborate on this a bit more? What's the
problem with helpful compiler messages?

Walter likes helpful error messages, but I think he doesn't want
to:
1) Use too much time to improve them. There are usually more
important problems to fix.
2) Slow down the compiler (or make it use more RAM) to generate
better errors (this seems to happen if you want the column number
too of the error).
3) Produce too much long error messages because he thinks most
people are annoyed by a command line interface that gets too much
scrolling caused by many long error messages (I think most people
think this is a bit ridiculous justification).
But if you want to add/improve specific error messages, then ask
for the specific improvements in D Bugzilla as enhancement
request.

That looks great, thanks, although it's a bit cluttered with
all those languages ;-)

That 'clutter' is the real purpose of that site.
If you know language X, you don't know language Y but you want to
learn language Y, often in that site you are able to find the
same algorithm/code implemented in both X and Y. Comparing them
you are able to learn some Y and the best idioms of Y too. Just
like the true Rosetta Stone did for Egyptian language :-)
That site has other secondary purposes:
- There you often find good computer science ideas or good
programming ideas/tricks to learn from.
- Comparing the same algorithms in many very different languages
you are sometimes able to catch better the essence of an
algorithm, that is what's invariant of those implementations. A
good book that introduces to algorithms is supposed to show this
"essence" but often it doesn't, because a book on algorithms like
the one by Robert Sedgewick is mostly procedural, even if he has
written books for Java, C, C++. On that site you find wildly
different implementations based on different programming
paradigms, like templates, pure lazy functional, dynamic
homoiconic functional, parallel, OOP, logic programming,
concatenative programming, stack-based, even flow programming.
All those programming paradigms are usually absent on books like
Robert Sedgewick ones. And often the comparison teaches you
something. Because sometimes an algorithm or data structure must
be changed to fit (otherwise you get things like QuickSort or the
Sieve of Eratosthenes implemented naively in Haskell, with so bad
performance that they essentially have become a different
algorithm).
- If you are interested not just in algorithms (or little
programs) and their implementations, but also in programming
languages themselves and their design, then that site helps you
slowly gain a broader vision of what different languages offer to
solve specific problems, what the "taste" of a language is, what
languages are elegant or not, what languages seem an
agglomeration of features, what languages are practical
"engineering products" like D or not, what type systems seem
intrusive and what are too much rigid, and so on and on. So if
you want you are able to use that site to learn how to design
languages too, a bit.
- That site has several other smaller purposes.
Bye,
bearophile

You can use toStringz() from std.string to convert D strings to
null terminated strings when you need to interface with C
functions. But in this case, writeln() would be the simplest
solution. It would be only:
writeln(foo());
Instead of:
printf("%s\n", toStringz(foo()));
I'm a newbie in D too, so correct me if there is anything wrong.