A paper about traps and programming stress
bearophile
bearophileHUGS at lycos.com
Mon Mar 15 08:08:37 PDT 2010
F:
>would like to verify the robustness of D with respect to the issues presented in the paper...<
In some of those cases D gives tools to solve the problem, but to use those tools the programmer must already know about those problems.
--------------------
Illusory protection: D classes of the same package can't access each other protected members.
But in a D module even private attributes can be accessed by everyone else in the same module. The compiler here doesn't even try to give warnings. This can lead to bugs. A @superprivate or @module property can help here :o)
This D characteristic of allowing free access in a module is bad for newbies because this langage sloppiness does not help learn the meaning and usefulness of the public/ protected/ private attributes.
--------------------
Constructor confusion:
In D this prints:
3
3
import std.stdio: writeln;
import std.math: PI;
class Super {
this() { printThree(); }
void printThree() { writeln("three"); }
}
class Test : Super {
int indiana = cast(int)PI; // That is, pi=3 in Indiana.
override void printThree() { writeln(indiana); }
}
void main() {
auto t = new Test;
t.printThree();
}
--------------------
Initialization follies: in D I think D Scope Guard Statement as scope(exit) can help here.
--------------------
Inheritance without specialization: in D there are class mixin that can be useful to use aggregation instead of inheritance (but they are a low-level feature that can cause other problems). Some templates can be used to inject other functionality in class templates. The @disable can be used to hide inherited members:
class Foo {
void method() {}
}
class Bar : Foo {
@disable override void method() {}
}
void main() {
auto b = new Bar;
b.method();
}
It raises a compilation error like:
test.d(9): Error: function test.Bar.method is not callable
Even if something like this can be better:
test.d(9): Error: function test.Bar.method is not callable, annotated with @disable.
--------------------
Container limitations: D has templates that were designed to solve this problem. In the meantime part of this problem has being solved for Java too, this article if from year 2000.
--------------------
Not-so-final parameters: the D const system is transitive, this solves the problem with method/function arguments. const can be used to state that a nonstatic method doesn't change the object state:
class Foo {
int x;
const void bar() { x++; }
}
void main() {}
--------------------
Initialization diffusion: D classes don't have instance initialization blocks. But both modules and classes can have multiple static this, so they can suffer the same diffusion problem:
int a, b;
static this() { a = 10; }
class Foo {
static this() { Foo.x = 10; }
static int x, y;
static this() { Foo.y = 20; }
}
static this() { b = 10; }
void main() {}
Allowing only one static this() in a module/class can help. I don't think a class/module can necessitate more than one static this, so this can become a bug report. Others here can give their opinion on this.
--------------------
Other worries:
No separate class-specification: I don't agree this is a problem. (dmd can generate 'header' files, but they are for performance purposes).
No support for assertions: D has asserts and Contract programming. Phobos2 has enforce.
Array type-checking failures: this D version of the program doen't fail at runtime:
class A {}
class B : A {}
void proc(A[] x, A y) {
x[0] = y;
}
void main() {
B[] anArrayOfB = new B[5];
A a = new A();
proc(anArrayOfB, a);
}
--------------------
bye,
bearophile
More information about the Digitalmars-d
mailing list