
On Jun 28, 2007, at 12:17 PM, Greg Meredith wrote:
Haskellians,
Once you have a polymorphic let, why do you need 'let' in the base language, at all? Is it possible to formulate Haskell entirely with do-notation where there is a standard monad for let environments? Probably this was all discussed before in the design deliberations for the language standard. Pointers would be very much appreciated.
Best wishes,
--greg
I've been wondering the same thing. When I want a break from coding, I rewrite files in an imaginary language to see what I want, what comes naturally. Let is the first keyword to go; a binding on one line followed by an expression on the next ought to imply a let/in combination. Looking at special "do" language support for monads and arrows reminds me of special language support for tuples and lists. While it would probably be painful to lose all syntactic sugar, I would prefer a uniform mechanism for supporting any future construct like monads and arrows, so "adding language support" isn't restricted to the implementors. Monads and arrows are particular instances of a general functional programming idiom, and seeing how preciously they are treated reminds me of the early history of mathematical group theory, when people treated each of the few groups they knew as a one-off special case. No programming language should treat monads and arrows this way. I'm struck by the "readability" requirement that leads to explicit
= syntax, or "adding language support". Readability should be a compiler option: You can't read someone else's code or your own weeks later? Have the compiler massively annotate the type information back into the code, supplying implied combinators, to a web page you can carefully study.
If one gets over a requirement that raw code be readable, then all sorts of combinators can be implied. Using type information, the compiler would be able to notice that two successive lines of code make no sense at all in sequence, but WOULD make perfect sense if a
= was inserted. This is roughly what a do statement does, except a do statement does this in an ad hoc fashion for a very few combinators.
Rather than having a short ad-hoc list of operators inserted by do, analogous to the short ad-hoc list of syntactic sugar for tuples and lists, one could have a general class mechanism for inserting arbitrary combinators. This would get confusing to read, but a compiler that could annotate code with explanations of what it did would help. Now, we're instead forced to write these annotations manually, and stare at them all of the time.