Equivalent of Haskell do-notation or F# Computation Expressions in Scala?
Asked Answered
C

2

7

F# Computation Expressions allow to hide the complexity of monadic syntax behind a thick layer of syntactic sugar. Is there something similar available in Scala?

I think it's for comprehensions ...

Example:

val f = for {
  a <- Future(10 / 2) // 10 / 2 = 5
  b <- Future(a + 1)  //  5 + 1 = 6
  c <- Future(a - 1)  //  5 - 1 = 4
 } yield b * c         //  6 * 4 = 24

 val result = f.get

But it doesn't really feel right. Is there a better syntax?

for exemple in haskell you would have

    main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode
          toHandle   <- getAndOpenFile "Copy to: " WriteMode 
          contents   <- hGetContents fromHandle
          hPutStr toHandle contents
          hClose toHandle
          putStr "Done."

this unlike scala doesn't look like a foreach loops. Scala syntax seem to have too strong coupling with List comprehension which is a distinct concept. Which prevent me from writing internal DSL (monad) that doesn't look strange.

Catatonia answered 20/9, 2011 at 3:55 Comment(12)
for comprehensions is exactly right. They desugar to map and flatMap behind the scenes, which is exactly how Haskell do notation works (except those methods are called fmap and >>= in Haskell).Georgeannageorgeanne
@pelotom I'd love to see an answer that explains a bit more of that.Thermometer
@Dan Burton - This question has been asked and answered several times... I'll refer you to this excellent answer: #1052976Georgeannageorgeanne
Correction to my first comment... fmap is actually not used in Haskell desugaring of do-notation, because there is no yield statement which necessitates it (and also we can't be sure all Monads are Functors, even though they should be)... instead of a keyword yield you just use the return function which, when called as the last statement in a do block, amounts to an fmap.Georgeannageorgeanne
What is it about the notation that doesn't feel right?Breaker
@DanielC.Sobral: well he's quite right in that for is too strongly associated with looping; there's no way around it; extracting values from Options reads quite awkward (especially to the untrained eye) using a for-loop like syntax, and I'm still not comfortable with it after a few months, especially when somebody else looks at the code who might not be a Scala expert.Chainey
@ErikAllik That's just a result of a limited experience in computer languages. It's funny that one says "for is associated with loops", when on a bunch of languages the keyword is loop, or do/loop, with no for in sight. So, I get and respect that one might feel this way, but the thing to do is get over it, in my opinion.Breaker
@DanielC.Sobral: I don't see how the following logical construction makes sense: "because some languages don't use for for looping, for should not be assumed to be associated with looping"Chainey
@ErikAllik It makes as much sense as "because some languages use for for looping, for should be assumed to be associated with looping", so you don't have a leg to stand on. Regardless, that's not what I said. What I said is that this association is a result of limited exposure to programming languages -- being forced to drop unreasonable assumptions (loop is reasonably associated with loops, but for?) is a result of expanding your horizons, and Scala is as good a start as any for that.Breaker
@DanielC.Sobral: which other languages besides Scala use for for constructs other than looping?Chainey
@ErikAllik I have no clue, and that's not the point. The point is that there's nothing special about "for" to indicate loops, many other languages use loop for them, and that people learning more than a few closely related languages should be prepared to drop the conventions learned from those languages.Breaker
We can just keep arguing forever of course but it won't change the fact that for most people for associates with looping, and for a good reason. Yes, it's possible to "get over it", but that doesn't change the point really.Chainey
C
-2

It seem like there is no such syntax available in scala and we would need to implement it ourself using the compiler plugin architecture.

Catatonia answered 26/9, 2011 at 20:14 Comment(1)
I've thought of using macros—have you considered that?Chainey
S
4

The missing piece is probably the use of = is scala's for-comprehensions:

val f = for {
  a <- Future(10 / 2) // 10 / 2 = 5
  b <- Future(a + 1)  //  5 + 1 = 6
  c <- Future(a - 1)  //  5 - 1 = 4
  d = b * c           //  6 * 4 = 24
} yield d


val result = f.get

With judicious mixing of both <- and =, you should have all the flexibility you need.

Scutter answered 20/9, 2011 at 8:31 Comment(1)
Sometimes I wish Haskell's do syntax would infer let from the use of =Thermometer
C
-2

It seem like there is no such syntax available in scala and we would need to implement it ourself using the compiler plugin architecture.

Catatonia answered 26/9, 2011 at 20:14 Comment(1)
I've thought of using macros—have you considered that?Chainey

© 2022 - 2024 — McMap. All rights reserved.