Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Haskell-inspired monadic do notation #222

Merged
merged 2 commits into from Dec 11, 2018

Conversation

@ericvm
Copy link
Collaborator

commented Nov 7, 2018

Haskell-inspired monadic do notation
it allows one to drop the _ when we don't need the extracted value
Basically,

  (do-let
    a
    b
    [c d
     e f]
    x
    y)

Translates into:

   (mlet
    [_ a
     _ b
     c d
     e f
     _ x]
    y)

For some monadic idioms, the stream of transformations itself is more important than the final result.
Also, sometimes there are many extracted values that we actually don't care about. For these cases, it may be more readable and clean to use a macro like do-let instead of mlet for monadic composition.

ericvm added 2 commits Nov 7, 2018
@caioaao

This comment has been minimized.

Copy link
Contributor

commented Nov 7, 2018

I'd change it to this to avoid having to use (do ...) as the final argument and make it clearer as to what is the body and what are the bindings:

  (do-let
    [a
     b
     [c d
      e f]
     x]
    y)
@ericvm

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 8, 2018

@caioaao The whole point of the macro is not to give any "special status" to the last form. There is no body, it is just a chain of bindings.

If you really wanna do other things you can use do or :let

@fabioyamate

This comment has been minimized.

Copy link

commented Nov 8, 2018

It lacks the support that mlet have.

For example:

(mlet [x (maybe 1)
    :let [y (+ x 1)] ; local definition
    :when (pos? y) ; guards
    z (maybe 3)]
  (return (+ z y)))

so I'd prefer the _ + mlet over this one.

plus, given it is clojure, not sure if implicit return at end would be better.

AFAIK, (mlet [x (maybe 1)] x) it returns 1 not maybe 1

@ericvm

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 8, 2018

@fabioyamate do-let gets translated directly to mlet so it is possible to use all of mlet features

So, you can do:

(do-let 
  [x (maybe 1)
   :let [y (+ x 1)] ; local definition
   :when (pos? y) ; guards
   z (maybe 3)]
  (return (+ z y)))

That will translate directly to the mlet you described. Also, there is no implicit return.

@ericvm ericvm merged commit 7fd5f98 into funcool:master Dec 11, 2018

@ericvm ericvm deleted the ericvm:do-let branch Dec 11, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.