On Saturday, 8 February 2014 at 05:43:44 UTC, logicchains wrote:
apart from superior compile-time metaprogramming? Personally, I think working to improve the garbage collector could pay off in this regard; "Both Rust and D allow you to choose between using a garbage collector and using referencing counting, but D's garbage collector is a precise concurrent generational moving compacting collector, whereas Rust's is a non-parallel non-moving conservative collector that's orders of magnitude slower and uses much more memory." Currently, even Go has a better GC than D.

Well, I think the main problem with D is that it is not a spec driven language, but an implementation driven language and that the implementation is based on compiler backends with very restrictive C semantics. D tries to bolt higher level functionality on top of that without opening up for efficient implementation of such features.

For instance:

1. You could have GC free lambdas if you require that they only call functions that can work with fixed-size stack frames (so you allocate stack frames off a thread local heap where all allocation units are of a fixed size (say 1k)) and that they avoid recursion.

2. You could avoid lots of temporary allocations and copies if you could control what stack frames look like, by modifying the parent frame.

3. You could have zero overhead exception handling if you could get rid of the silly backwards-compatible driven design of Dwarf:

- If you fully control code gen you can have dual return points with a fixed offset, so you can modify the return address on the stack by adding an offset before returning to indicate an error or just jumping. The penalty is low since predicted branches tend to be cheap.

- If you don't need stack frames (by not having GC) you can maintain only frame pointers for function bodies that contains try blocks. Then jump straight to them on throw:

Throw becomes:

reg0 = exception_object
JMP *(framepointer+CATCHADDR)

Catch becomes:

switch(reg0.someid){
...
default:
   framepointer = *(framepointer+NEXTPTR)
   JMP *(framepointer+CATCHADDR)
}

This would make for very efficient exception handling with no more setup cost than you have today for stack frames. I believe.

It isn't reasonable to require that you write a backend from scratch, but I think it is reasonable to have a language spec that does not tie you to an implementation that will never go beyond C. If that makes adapting existing backends slightly less efficient, then that should be ok. It is more important to have a language spec that allows future compilers to be highly efficient.

- If you want mandatory GC, ok, but then change the language spec to make it possible to write a powerful compiler.

- If you 100% C++ parity/compatibility, great, but then make it just as easy (or easier) to write C++ type code without GC. Basically, you would have a language that consists primarily of syntactic sugar + some optimizing opportunities.

- If you want better performance than C. Great! But don't limit the language to C-semantics in the backend.

Make a decision for where you want to go at the language specification level. Forget about the current compiler/runtime. Where do you want to go?

Reply via email to