Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Scala equivalent to Clojure's threading macros?

Tags:

scala

clojure

Clojure has the "threading macros" -> and ->>. I'm pretty sure a similar construct can be used in Scala code to replace code like:

var myObj = MyObject(x, y, z)
myObj = transform(myObj, abc)
myObj = transformMore(myObj, def)
myObj = transformYetMore(myObj, bar)

I'd love to see a worked-through example to see if it looks good. I'm pretty sure you don't need to use macros in the Scala case.

like image 625
tksfz Avatar asked Nov 14 '13 22:11

tksfz


1 Answers

Good question! I can think of several instances where something like this can come in handy. To give an example, I am working with a dataset and I want to apply several functions on it while carrying the results forward like this:

val result: ResultSet = Functions.thread(inputSet)
                                 .andThen(execute(_, executionContext))
                                 .andThen(_.filter(_.nonEmpty))
                                 .andThen(verifyData(_, verificationHelper))
                                 .andThen(_.cache)
                                 .andThen(saveSnapshot)

To write the same without threading, you will need to either nest calls or save results of intermediate function calls. I prefer using the above method as it does the same thing in less number of lines which improves maintainability and readability of my code.

Here is the Functions utility to achieve this:

object Functions {
  def thread[T](item: T) = new ThreadFunctor(item)
}

class ThreadFunctor[T](val item: T) {
  def andThen(f: T => T): ThreadFunctor[T] = new ThreadFunctor(f(item))
}

object ThreadFunctor {
  implicit def threadToItem[T](thread: ThreadFunctor[T]): T = thread.item
}
like image 91
nuaavee Avatar answered Nov 08 '22 20:11

nuaavee