“…problem like this are damaging if one is trying to present programming as a discipline subject to mathematical analysis.”
because in general programmers steadfastly refuse to subject their discipline to mathematical analysis, and continue to look for some aesthetic balance between "enough abstraction" and "enough whitespace".
Here is a program to sum a list of numbers:
+/
This definition is even less cumbersome than the Miranda or the Lisp, but it's unclear what the author expects us to conclude from this. And yet I think it's perfectly reasonable to posit that shorter programs are better. Shorter programs have less bugs[1], and run faster[2], and yet for some reason there are a lot of programmers who believe their job is to produce more code. Fuck those guys. Seriously.[1]: See Code Complete and Software Estimation: Demystifying the Black Art, by Steve McConnell.
[2]: https://stacresearch.com/m3
Then we have the pursuit of "traditional mathematical notation": I don't think it produces better programs or better programmers. Computers do not execute mathematical notation, and mathematicians can't agree on their notation to enough specificity to permit as much useful computation[3]. It is clear that notation is important[4], but there is frighteningly little real research in this space. Zero-cost abstractions still take up source code, and yet many programmers think this is given as a good thing, despite Dijkstra’s wonderfully succinct observation:
“…the intellectual effort needed to conceive or to understand a program need not grow more than proportional to program length.”
[3]: See Whitehead and Russell, Principia Mathematica
[4]: http://www.jsoftware.com/papers/tot.htm
Lazy is also bad. Computers aren't lazy. Starting off by thinking about them as lazy puts programmers on that path for total abstraction. So much energy has been put into trying to hide concurrency-problems[5] that it's no wonder most big-data programs generate so much heat. The real value in Scheme Streams is that they're explicitly concurrent, and other languages that have optimised for those constructs[6] have discovered a great deal of utility.
[5]: http://hadoop.apache.org/
[6]: O=spawn(fun(P)->P!{f,self(),F()} end,[self()]), receive{f,O,X}->X end.
It's almost like we've plucked some ideas, said they're important, and then used them as a lens to study our languages without even doing the first thing by showing how we can know they are important to the point of excluding everything else.
About the only thing I really like about Miranda (and Haskell, etc) is the pattern matching, which is dope. Seriously good stuff. I don't know how to square that with array languages, but I think it's worth thinking about since they (array languages) seem to have otherwise sorted out program length and notation.