If you could make any changes to D, what would they look like?

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Oct 25 16:31:36 UTC 2021

On Mon, Oct 25, 2021 at 02:52:55PM +0000, Dennis via Digitalmars-d wrote:
> - Module constructors

Module ctors are da bomb!  You can do all sorts of awesome things with
them, if you know how to combine them with compile-time introspection
and other metaprogramming techniques.  It's part of why Adam's jni.d
module is so awesome.

> - `lazy` parameters

I rarely need this, so meh.  I guess it's nice to have when you do need
it, but so far I haven't.

> - `in` / `out` parameters

IMO these are very useful.

> - `in` / `out` contracts

These too, except the implementation could be improved.

> - Function body literals (`{}` instead of `() {}`)

One can argue about syntax till the cows come home, and we wouldn't come
to an agreement. :D

> - Typesafe Variadic Functions (`foo(int[] a...)`)

These are awesome!  Lets you construct array arguments on the stack
where a function accepting only an array would force a GC (or other)

> - String literals starting with `q`

Heredoc literals are awesome, I use them all the time.  They make
code-generating code actually readable, instead of being candidate
submissions for the IOCCC. :-/

Though I can see how the proliferation of different string literals make
the D spec somewhat unwieldy...

> - The remaining octal literals (00-07)

Yeah, kill octals with fire and extreme prejudice. :->

> - `is()` expressions

Yeah they are a mess. Well, not so bad once you understand the logic
behind them, but still, they're very opaque for a newcomer.  And there's
also the odd hidden dark corner that will make even a seasoned D veteran
cringe, e.g.:


But is() expressions are also the backbone of much of D's
metaprogramming prowess, so unless you come up with something better,
they are here to stay.

> - `switch` with run-time variable cases

Yeah... I generally avoid using switches in that way. It just makes code
hard to read.

> - `switch` with string cases

This is actually nice for some cases.  But the current implementation
involves instantiating a template potentially with a huge number of
arguments (*ahem*cough*std.datetime*ahem*), which at one point caused so
much grief we had to rewrite either std.datetime or the druntime
implementation of the string switch, I forget which.

> - `alias` reassignment

Whaddya mean, that's one of the best things to happen to D lately, that
gets rid of a whole bunch of evil recursive templates from druntime and

> - `__traits(compiles)`

Yeah, this one's a loaded gun.  It seems a good idea on the surface,
until you realize that most (all?) of the time, you actually don't
*mean* "does this code compile"; usually you have something much
narrower in scope like "does X have a member named Y" or "is X callable
with Y as argument".  Using __traits(compiles) for this quickly leads to
the problem where you *can* call X with Y, or X does have a member named
Y, etc., but there's a typo somewhere in the code that makes it
non-compilable, so suddenly your template overload resolution goes in a
completely unexpected direction generating screenfuls of completely
unhelpful and irrelevant errors.

> - `opDispatch`

opDispatch is awesome. See: Adam's jni.d.

> - `opCall`

opCall is needed for function objects. How else are you supposed to
reify functions when you need to?!

> - `opApply`

This is actually useful in cases where the range API may not be the best
way to do things (believe it or not, there *are* such cases). One
example is iterating over a tree without needing to allocate more
memory for the iteration.


My program has no bugs! Only undocumented features...

More information about the Digitalmars-d mailing list