I think a proper type system that doesn't special-cases arrays are better, e.g. Array<String>. Pointers may also be part of this uniform structure, e.g. Array<Ref<String>>, and there is zero question on how to parse it even if you are not familiar.
You can't really encode a tree structure with only linear semantics (without at least something like s-expressions).
The advantage of type after name is that it keeps the traversing order consistently pre-order (node, left, right), instead of either:
- the notoriously ridiculous spiral cdecl: reading stuff right (output), node (func name) and left (input)
- create a new name to describe the function in pre-order: Func<Input, Output>
At that point I find a uniform system (without special-casing arrays and pointers - they are also just types) would be simpler.