
Hi
let x = 12 let x = (<- x)
Okay, so the desugaring process wouldn't terminate in that case! One could either: (a) try to retain the equivalence in theory, but make it illegal to use x in a monadic subexpression when defining x; (b) we could abandon my claim that they are equivalent.
This example isn't intended to be about termination of the desugaring, or about types etc - the only point is to note the change in the lexical scoping rules that (<-) gives. I'll try and state my concern more clearly: let x = a In this expression, x is available for use within a, since let is recursive. This allows us to write: let xs = "paws" : xs With the end result that xs is bound to ["paws","paws","paws","paws"... Now consider: let x = (<- a) With the proposed desugaring we obtain: temp <- a let x = temp Now x is NOT in scope within the expression a! We have changed the static lexical scoping, and only within the brackets. This behaviour is (in my opinion) horrid. A quick poll of people in my office lead us all to believe that this issue means you should not be allowed (<-) within a do's let statement. This leads us to a second problem, floating these monadic expressions outside any binding: do case x of [] -> return 1 (y:ys) -> f (<- g y) Here, the proposed desugaring does not work, since y is not in scope where we move the element to. Perhaps this leads to the conclusion that monadic subexpressions should not be allowed inside any binding group, including let, case or lambda. Thanks Neil