Top 5

Adam D. Ruppe destructionator at gmail.com
Wed Oct 8 16:14:05 PDT 2008


On Wed, Oct 08, 2008 at 03:07:27PM -0500, Andrei Alexandrescu wrote:
> Ok, per Aarti's suggestion: without speaking officially for Walter, let 
> me ask this - what do you think are the top issues you'd like to see 
> fixed in D?

1: There is a compiler bugs I'd like to see worked out that cause
my code to randomly crash or behave incorrectly on Windows, but not Linux.
(Sadly, I haven't tracked this down yet, so I can't point to a specific bug
report.) This is very vague, I know, but the main idea is I'd like the
compiler to always generate correct code as much as realistically possible.

2: D programs are a bit fat on memory usage. Not greatly, but when I'm
writing code for my old 1995 laptop, I still use straight C to better use
of the limited resources. I think a better GC and the standard lib only
linking in what is needed should help this.

3: Again, linking in only what is used in the stdlib will solve this one
I believe: trimming down the size of D executable files. Again, when I need
small exes, I still feel that I need to write C.

4: I find D's contracts to be cool, but not terribly useful in practice.
I really don't know how to fix this: maybe contracts in an interface would
help.

5: I'm actually having a hard time completing this list... oh, here's one.
Touching member objects in a destructor is undefined behaviour, since the
garbage collector can reap them ahead of time unless the object is deleted
manually.

To fix it, what I think I'd like is a type modifier to make this ok.

class A{
  SomeObject a;
  unmanaged SomeObject b; // my addon: tell the GC to not manage this object.
  ~this(){
	a.whatever();  // if the object is garbage collected, this might crash,
			// since the garbage collector might have already
			// deleted a. Thus, I think it should be a compiler
			// error to access it this way.
			// UNLESS, SomeObject is guaranteed to be
			// deleted deterministically, such as if it is a
			// scope class (or if it is unmanaged as well.)
	b.whatever(); // this, however, is safe in my proposed addition, since
			// b is marked unmanaged, meaning the garbage collector
			// leaves it alone.
  }
}


While I propose a modifier above, that could probably be done as a template
(though I haven't really thought about it), I do think the current behaviour
of allowing the destructor to be potentially dangerous is less than optimal.

That said, I'd prefer keeping access to a.whatever() like it is now over
banning it without some kind of workaround, since if I manually remember
to delete the object, the above code works correctly.





Stuff I'd like to see added, in no particular order:

1) Writing to global variables in type constructors - whenever an object
of a particular type is constructed, I can run a compile time function
and do something with that value, like append it to a global array.

string[] allPrintedStrings;
typedef PrintedString (string value) {
	allPrintedStrings ~= value;
	return cast(PrintedString) value;
}; // this semicolon might not be desired, but is here since typedefs normally
// end with them.

(The syntax here probably sucks.)

Whenever a PrintedString is declared in the code, the function in the typedef
is called at compile time only (not runtime - for that, I'd just use regular
constructors) and creates a global array of all the values in the code.

Now my main() might do foreach(s; allPrintedStrings) writefln("%s", s); and
list them all off, so say, a translator could see all those strings and do
his job a bit more easily.


Right now, I think the only way to accomplish this is with a preprocessor.
The above example is trivial to implement with a simple add-on preprocessor,
but I think it might be more useful built into the language.



2) Subtype typedefs - something like inheritance, but with typedefs instead
of classes, so there is no runtime overhead. It is like a weakened typedef.
So "typedef extends string PrintedString;" or some such syntax is like doing
class string {}
class PrintedString : string {}

As far as the type system is concerned.

The new template constraints I believe can do this now, but this would be
prettier:
	PrintedString a = cast(PrintedString) "Hello, world!";
	std.string.split(a, ',');  // this works since we get the implicit
				   // downcast to the base type of string.
				   // At runtime, the PrintedString and
				   // string are identical anyway, so no
				   // templating is necessary.




I think that's all that's on the mind right now.

-- 
Adam D. Ruppe
http://arsdnet.net



More information about the Digitalmars-d mailing list