One issue with D's design is that it uses

char a[..]

as syntax for a pointer, not an array. C has the same confusing issues in prototypes where it allows char[] notation for pointers, but this as it is widely seen as a mistake.

I do not agree that C VLAs are a terribly clumsy design. Especially from the point of dependent typing, C's design is the right one, e.g. you can express something such as

void transpose(int X, int Y, double (out)[X][Y], const double (in)[Y][X]);

If you only have existential types and not the fully dependent form, then this is not possible.

D does not use `char a[..]` as syntax for anything.

A pointer is declared as `char* p`, and an array as `char[] p`.

A two dimensional array parameter is declared as:

    void transpose(double[][] a);
Having to specify the dimensions as separate parameters is an unfortunate design choice:

1. It's clumsy to have to carry the dimensions around as separate items, rather than as one item

2. If the wrong X or Y is supplied, you have a massive memory corruption problem

I took the syntax from your article, maybe it is not what D is using now.

It is more expressive to pass the dimensions as separate variables. This is also exactly what other dependently typed languages do. The memory corruption can be avoided by having the compiler check this. I agree though that fat pointers are more convenient and would should also have them as syntax sugar on top of it.

The syntax in the article is what I proposed for C. Sorry that wasn't clear.

Yes, the separate variables is more expressive. It's also clumsy, inelegant, and error-prone. It also only works for function calls - not fields in a struct.

the pointer stars got lost, sorry.

  void transpose(int X, int Y, double (*out)[X][Y], const double (*in)[Y][X]);