Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

Bugs in do-notation #5

Open
raimohanska opened this issue Dec 18, 2013 · 5 comments
Open

Bugs in do-notation #5

raimohanska opened this issue Dec 18, 2013 · 5 comments

Comments

@raimohanska
Copy link
Contributor

I'd like to use do-notation for Async monad (the thing in my blog). I did some experimenting and found a couple of issues with the do macro.

So firstly, I cannot

$do {
  x <- Async.of("cats")
  y <- Async.of("dogs")
  Async.liftIO(function() {
    console.log(x, y)
  })
}

.. because the macro requires the last expression to be a return.

I'm happy though that this indeed works:

$do {
  x <- Async.of("cats")
  y <- Async.of("dogs")
  return console.log(x, y)
}

The second problem is that multiple returns don't work, so I can only 1 "naked IO" per do-block. See failing test case: 9940a1e

Also, var bindings in the "tail" do not work as in

$do {
  x <- Async.of("cats")
  y <- Async.of("dogs")
  both = x + y
  return console.log(both)
}

There's a failing test case for this too, at 3fb4326.

Having said this all, I still want to thank you for all these Sweet Fantasies! I think there's good stuff on the way but it needs some polishing first. Sorry for not having time to start looking for fixes yet.

@raimohanska
Copy link
Contributor Author

Oh yet another thing. You cannot

$do {
  x <- Async.of("cats")
  y <- Async.of("dogs")
  return console.log("hello", x, "and", y)
}.run()

i.e. put anything on the same line as the macro. That might be a sweet.js feature?

@jonifreeman
Copy link

The first one is a known limitation (https://github.com/puffnfresh/sweet-fantasies/blob/master/src/do.sjs#L39). I was unable to make that work with sweet.js 0.1. We should look into that again now that sweet.js is upgraded to 0.2.

'var bindings in the "tail" ' is probably just an oversight and easy to fix. Support for multiple returns may require some larger refactorings on how the macros are currently done.

@markandrus
Copy link
Contributor

One var binding in the tail is an easy fix. Multiple var bindings in the tail is trickier. I think it should be writable as a repeated pattern, but couldn't get it to match.

@markandrus
Copy link
Contributor

Actually, changing the $x:ident = $y:expr rules to be preceded by let $x:ident = $y:expr allows the repeated pattern let $($x:ident = $y:expr) (let) ....

This would allow one or more var-bindings in the tail

$do {
  x <- Async.of(1)
  y <- Async.of(2)
  let plus = x + y
  let minus = x - y
  return console.log(plus * minus)
}

Edit: maybe var instead of let would be more appropriate?

@markandrus
Copy link
Contributor

I believe there are many more cases we haven't accounted for, but I encountered some trickiness supporting if-statements and took a break working on it: https://gist.github.com/markandrus/8795723

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants