News for hackers. Stuff that matters.
Re:Why we love Scala at Coursera by dmunoz on Tuesday February 18, 2014 @01:36PM (#7260021)
I enjoyed reading this article, but does anyone who doesn't already understand what they're saying understand after reading something like:

"Play's reactive core and asynchronous libraries (e.g. WS) integrate seamlessly with other powerful concurrency primitives in the ecosystem such as Akka’s actors. Combining for-comprehensions with composable futures makes asynchronous concurrency look like straightforward synchronous code."

I get the gist, but I had to go and search for what for-comprehensions were. According to [0], they're a syntactic sugar over map. Then, if I search for composable futures (I know those words separately, but can only guess about them used together) I seem to only get results for Akka 2.0. The first result I click on is for a 167 page book for $23 USD. Maybe that is my fault, as the first result is actually to Akka documentation, but when I click there there is no mention of the word composable. The next two links are to slides of a presentation by the author of the first link I mentioned, and then to a video of the presentation. The fourth is to an early access of the same book, the next a blogspam to the video presentation. I gave up here.

For an article that is arguing for scala in comparison to PHP, Python, and Go, I didn't walk away with anything more than "sounds nice, but is it really?"

Code example would've helped.

[0] http://tataryn.net/2011/10/whats-in-a-scala-for-comprehensio...

Edit: Calling it "an article that is arguing for scala in comparison to PHP, Python, and Go" is a misrepresentation. It's really just about why they like scala, but they do do plenty of hand-wavy comparisons with other languages.

Edit 2: Okay, I see the Akka documentation does have a section "Composing Futures" that I missed.

Re:Why we love Scala at Coursera by saryant on Tuesday February 18, 2014 @01:58PM (#7260203)
A for-comprehension from our production code:

  for {
    createResult  <- Graph.createPerson(person) 
    _             <- Search.putAll[Person](createResult \ "updated_nodes")
    _             <- Search.deletePersons(createResult \ "deleted_nodes")
  } yield {
    Created(createResult \ "node")
  }
That code asynchronously updates both ElasticSearch and Neo4j. Those functions all return Scala futures containing JSON values. First the new object is created in Neo and then the index in ES is updated accordingly. This is in a controller action in a Play project where it's critical to keep everything non-blocking. If everything is successful, Play returns a 201 result to the requestor, otherwise there are error handling functions elsewhere that kick in.
Re:Why we love Scala at Coursera by NickPollard on Tuesday February 18, 2014 @02:13PM (#7260322)
Scala derail: You might have an unintentional happens-before relationship in that example: The deletePersons call will end up being in the flatMap of the putAll[Person] call, which means it wont be started until the putAll finishes, when by the looks of it you could do both at once (only the createPerson needs to happen first).

You might want to do something like this:

  for {
    createResult  <- Graph.createPerson(person) 
  } yield {
    val a = Search.putAll[Person](createResult \ "updated_nodes")
    val b = Search.deletePersons(createResult \ "deleted_nodes")
    for ( _ <- a; _ <- b ) yield Created(createResult \ "node")
  } 
(notice starting the computations outside of the second for-comprehension, then just waiting for them inside)
Re:Why we love Scala at Coursera by saryant on Tuesday February 18, 2014 @02:16PM (#7260349)
Good catch. :) Our production code actually does handle the relationship correctly, I just wanted to simplify in my example.
Re:Why we love Scala at Coursera by dilap on Wednesday February 26, 2014 @06:34PM (#7309073)
What happens if the process dies in between createPerson and the search stuff? Are the Neo4j results kept around w/ the search index left stale, or is there some sort of wrapping transaction around it all?
Re:Why we love Scala at Coursera by virtualwhys on Tuesday February 18, 2014 @01:50PM (#7260131)

    val plusOne = for(x <- List(1,2,3)) yield x+1
desugars to:

    List(1,2,3).map(_+1) // or longhand, map(x=> x+1)
and:

    for(x <- List(1,2,3); y <- List(4,5,6)) yield x*y
desugars to:

    List(1,2,3).flatMap(x=> List(4,5,6).map(_*x))
So, composable futures means you can chain a bunch of futures together in a for comprehension and yield the successful or failing result without blocking.

The essential point is that if you have some Thing that implements map and flatMap, it can be chained through a for comprehension.

Only just dipping my toes in Haskell, but I must say that Scala is a truly wonderful language, one that makes my daily dev a whole lot of fun.

Re:Why we love Scala at Coursera by deckiedan on Tuesday February 18, 2014 @03:00PM (#7260655)
Would this be equivalent to:

    plusOne = (x+1 for x in (1,2,3))
And then the second example:

    mult = (x*y for x,y in zip((1,2,3), (4,5,6)))
In python?
Re:Why we love Scala at Coursera by virtualwhys on Tuesday February 18, 2014 @03:13PM (#7260720)
yup, not sure what Python does with your examples under the hood, but they're equivalent, and, I must say, nicely concise ;-)

In Scala I guess we could go zip-style and do:

    List(1,2,3) zip List(4,5,6) map{case(x,y)=> x*y}
but I was trying to demo for comprehensions and their relation to map/flatMap for the OP.
Re:Why we love Scala at Coursera by singingcheese on Tuesday February 18, 2014 @01:49PM (#7260121)
It made perfect sense to me, perhaps because I code in Scala for a living (even though I don't use either Akka or Play (yet)). It reminds me of the old comment about how unreadable French is because it looks nothing like English.
Re:Why we love Scala at Coursera by Sharlin on Tuesday February 18, 2014 @02:46PM (#7260582)
I don't think the target audience of the blog post was experienced Scala developers (that would just be preaching to the choir!) so the use of unexplained jargon should be kept at minimum to actually reach the audience.