
Neil Mitchell
Thinking on the semantic issue for the moment:
Can you use (<-) outside of a do block?
Good question, but my answer is a strong no! Syntactic sugar for monads has always been tied to do blocks; promoting it outside of contexts where "do" announces that you'll be using syntactic sugar seems like a very bad idea.
do b >> f (<- a)
where does the evaluation of a get lifted to?
I think it's rather clear that a gets moved before b. The example is confusing because the code is bad; not because of any new problems with this proposal.
Given:
if (<- a) then f (<- b) else g (<- c)
Do b and c both get monadic bindings regardless of a?
This is tougher, but I'd say yes. In this case, you've chosen not to give "then" and "else" clauses their own do block, so this would evaluate both. Certainly if/then could be made a special case... but it would be exactly that. i.e., if I did this: cond b th el = if b then th else el do cond (<- a) (f (<- b)) (g (<- c)) Then you'd lose. And the fact that you'd still lose there makes me less than thrilled to mislead people by special-casing if/then/else. When something is dangerous, it should be labelled as such as loudly talked about; but covered up in the hopes that no one will dig deep enough to hurt themselves.
if (<- a) then do f (<- b) else g (<- c)
Does this change to make b bound inside the then, but c bound outside? Does this then violate the rule that do x == x
Then yes, it would.
Can you combine let and do?
do let x = (<- a) f x
Right. In effect, as a matter of fact, the notation x <- a would become equivalent to let x = (<- a)
Our "best guess" is that all monadic bindings get floated to the previous line of the innermost do block, in left-to-right order. Monadic expressions in let statements are allowed. Outside a do block, monadic subexpressions are banned.
Sure. SPJ mentioned that you wouldn't promote (<- x) past a lambda. I'm not convinced (it seems to fall into the same category as the if statement), but it's worth considering. -- Chris Smith