Open robotlolita opened 10 years ago
Nice, you beat me to it :)
So, I took a stab at multiple returns, but there's some issues with it. The following code:
$do {
x <- Identity.of(a)
someAction()
y <- return b + x
return y + 1
}
Gets expanded to:
(function () {
var $do$op = Identity.of(a);
var $do$of = $do$op.of || $do$op.constructor.of;
return $do$op.chain(function (x) {
return someAction().chain(function (_it) {
return $do$of(b).chain(function (y) {
return $do$of(c);
});
});
});
}());
Rather than the simpler:
(function () {
return Identity.of(a).chain(funciton(x) {
return someAction()
}).map(function(_it) {
return b + x
}).map(function(y) {
return y + 1
})
}())
The meaning is the same, but the generated code is quite a bit more messy. Generating the simpler version should be possible, but would be quite a bit more of work. What do y'all think?
Oh, it also relies on the assumption that the $do block is well typed. If someone writes something like $do { x <- Identity.of(a); y <- Async.of(b); return c }
then the behaviour will be different (but in this case, I do guess the behaviour of that whole thing is undefined anyway?)
This addresses (https://github.com/puffnfresh/sweet-fantasies/issues/8), it's mainly a complete rewrite of the
do
notation macro. Other macros should probably be dropped now and rewritten using Sweet.js's custom operators (http://sweetjs.org/doc/main/sweet.html#custom-operators), as they make more sense as infix.This patch also supports having a naked action as the last expression, so:
Works and gets desugared as expected:
A couple of things worth noting about this patch:
_it
. This was mainly for simplicity dealing with all the cases, so:$do { a; b }
gets desugared toa.chain(_it => b)
. I'm unsure if this is much of a problem, though this does introduce an implicit new binding in the scope, which might lead to some awkward things(?)