Leandro Lucarella wrote:
5. simple interfacing to C
In case you mean no unnecessary wrappers etc., this has more to
do with the execution model than language features. Most
scripting languages are interpreted, and require some sort of
assistance from the runtime system. If the language was compiled
instead, they wouldn't necessarily need those.
In D you need interfacing code too, it can be a little simpler, that's
true.
The interfacing in D is nothing more than providing a declaration.
There is no code executed.
Unless you want to pass D strings to C, then you have to execute
toStringz(), which is a really thin "wrapper", but it's a wrapper. Using
C from D is (generally) error prone and painful, so I usually end up
writing more D'ish wrappers to make the D coding more pleasant.
You can also simply use C strings in D, and pass them straight to C
functions that take void*. No conversion necessary. It isn't any harder
to ensure a 0 termination in D than it is in C, in fact, it's just the
same. D string literals even helpfully already have a 0 at the end with
this in mind!
It's not safe, and of course, being a dynamic language, you can access
C code at "compile time" (because there it no compile time), but you can
interface with C very easily:
import ctypes
libc = ctypes.cdll.LoadLibrary("libc.so.6")
libc.printf("hello world %i\n", 5)
hello world 5
Wow, that was hard! =)
Ok, does this work:
p = libc.malloc(100);
*p = 3;
? Or this:
struct S { int a; char b; };
S s;
libc.fillInS(&s);
It's simpler, because you only have one obvious way to do things,
No, Python has try/catch/finally as well.
in D you
can use a struct, a scope class or a scope statement to achieve the same.
Of course that gives you more flexibility, but adds complexity to the
language. I'm not complaining or saying that D is wrong, I'm just saying
that Python is a very expressive language without much complexity. I think
the tradeoff is the speed.
Yes, you can emulate RAII with the with statement, but with RAII
(objects that destruct when they go out of scope) you can put this
behavior in the object rather than explicitly in the code every time
you use it. It's more complicated to have to remember to do it every
time on use.
Maybe you are right, but the with statement plays very well with the
"explicit is better than implicit" of Python :)
Again, is flexibility vs complexity.
Another principle is abstractions should be in the right place. When the
abstraction leaks out into the use of the abstraction, it's user code
complexity. This is a case of that, I believe.
There are static analyzers for Python:
http://www.logilab.org/857
http://divmod.org/trac/wiki/DivmodPyflakes
http://pychecker.sourceforge.net/
What's happening here is the complexity needed in the language is pushed
off to third party tools. It didn't go away.
And again, judging from experience, I don't know why, but I really have
a very small bug count when using Python. I don't work with huge teams of
crappy programmers (which I think is the scenario that D tries to cover),
that can be a reason ;)
Part of that may be experience. The languages I use a lot, I tend to
generate far fewer bugs with because I've learned to avoid the common
bugs. There have been very few coding errors in the C++ dialect I use in
dmd, the errors have been logic ones.
You're right that D has a lot that is intended more for large scale
projects with a diverse team than one man jobs. There is a lot to
support enforced encapsulation, checking, and isolation, if that is
desired. Purity, immutability, contracts, interfaces, etc., are not
important for small programs.