
On Thu, Aug 09, 2007 at 11:52:17AM -0700, David Roundy wrote:
On Thu, Aug 09, 2007 at 02:08:20PM +0100, Jules Bean wrote:
*snip*
A third example is with nested dos:
do x <- bar y baz something $ do foo x
is not the same as
do baz something $ do foo (<- bar y)
Again, it all comes down to whether the "find the nearest do" is obvious. It seems pretty obvious to me. And I like the idea of someone just implementing this, and then those of us to whom it appeals can try it. I've longed for something like this (mostly for monadic ifs and cases) for quite a while now...
Funny, I've been longing for the monadic case (and if) for quite a while. A mondic case is simple, it's handy, and you don't have to worry about lots of interactions caseM e of alts ==> e >>= \x -> case x of alts I'm convinced this would be plenty useful on its own, and also that trying to design any more comprehensive syntax quickly gets really tricky. The basic problem seems to be that functions can expect either monadic or pure arguments, and return pure or monadic values, so there are at least three possible conversion you might want at each application (considering pure<->pure and monadic<->monadic the same). Defaulting to "make things work" requires type information, and doesn't seem nearly so simple if you consider that programmers might actually want to pass around actions of the monad they are running in as values (Setting GUI callbacks, using [] for String processing, etc). Actually, deciding which tranformation gets juxtaposition and how to recurse into subterms seems to give a design space that might have reasonable solutions. More on that in a latter message.
There is also the fact that if : foo x = bar x x
then you call foo monadically as in
do foo (<- baz)
You can no longer "replace foo with its definition", because if replace that with
do bar (<- baz) (<- baz)
...that means something rather different :(
Again, this seems obvious, and it doesn't seem like "replace foo with its definition" is something I think of.
One of the great things about haskell is how completely naive you can be when you "replace foo with its definition", and still do valid equational reasoning. It would be sad if substituting a parenthesized subterm of something that looked like an expression wasn't valid. (expanding a definition can change sharing, but at least it's denotationally equivalent). The only slightly tricky things now are remembering that x <- exp does not define x to be exp, and what to expand a class method to. I think I'd be happier if there was some bracketing around the expression to be transformed, to warn you to again be cautious and fearful about transforming your code. Brandon