11

I'm wondering why is it so useful to put away the side effect part of a code using Kestrel. Does anyone has experience with it? and can explain the real motivation and how does it help exactly.

Although i understand that Pure functional programing is about zero-side effect and henceforth better debugging and predictability of the code. However in the case of Kestrel, I don't see how it really help to do that ?

Best,

MM-

MaatDeamon
  • 9,532
  • 9
  • 60
  • 127

1 Answers1

21

The point is to avoid creating an intermediate variable that you probably don't want to have lying around, or to avoid having to create a new block for something you're doing in passing. Let's suppose we have the Kestrel as in Ruby:

implicit class RubyKestrel[A](val repr: A) extends AnyVal {
  def tap[B](f: A => B) = { f(repr); repr }
}

Now let's suppose we have some line of code:

xs.map(_ + 7).filter(foo).take(n)

and we want to print out a debugging message after the filter. Without tap we refactor that line to:

{
  val temp = xs.map(_ + 7).filter(foo)
  println(temp)
  temp.take(n)
}

Ugh. Now suppose we have tap:

xs.map(_ + 7).filter(foo).tap(println).take(n)

Whew, way better!

Let's suppose we have a stack that has an add method, and we want to add something to the stack before using it somewhere else.

def newStack = {
  val stack = new Stack
  stack add "whatever"
  stack
}

Ugh. But with tap:

def newStack = (new Stack).tap(_ add "whatever")

Pretty handy--it really just lets you turn any normal side-effecting method into something that you can chain calls to. And since chained calls are often lower boilerplate, that's often a big win.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • That's also the need that naturally drove me to want a _tap_: I wanted to avoid having to creating variables and then repeat them at the end of the block. The code is shorter and more readable with _tap_ (to the point I think it should be part of Scala itself). – Frank Mar 13 '17 at 02:24