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.

skyde
  • 2,816
  • 4
  • 34
  • 53
  • 4
    `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). – Tom Crockett Sep 20 '11 at 04:40
  • @pelotom I'd love to see an answer that explains a bit more of that. – Dan Burton Sep 20 '11 at 04:44
  • 5
    @Dan Burton - This question has been asked and answered several times... I'll refer you to this excellent answer: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield/1059501#1059501 – Tom Crockett Sep 20 '11 at 05:14
  • 1
    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 `Monad`s are `Functor`s, 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`. – Tom Crockett Sep 20 '11 at 05:25
  • 1
    What is it about the notation that doesn't feel right? – Daniel C. Sobral Sep 20 '11 at 15:02
  • @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 `Option`s 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. – Erik Kaplun Mar 27 '14 at 03:13
  • @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. – Daniel C. Sobral Mar 27 '14 at 16:21
  • @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" – Erik Kaplun Mar 27 '14 at 17:31
  • @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. – Daniel C. Sobral Mar 27 '14 at 23:38
  • @DanielC.Sobral: which other languages besides Scala use `for` for constructs other than looping? – Erik Kaplun Mar 28 '14 at 00:42
  • @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. – Daniel C. Sobral Mar 28 '14 at 01:23
  • 1
    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. – Erik Kaplun Mar 28 '14 at 01:26

2 Answers2

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.

Kevin Wright
  • 49,540
  • 9
  • 105
  • 155
-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.

skyde
  • 2,816
  • 4
  • 34
  • 53