how to keep return value when logging in scala

What you’re looking for is called Kestrel combinator (K combinator): Kxy = x. You can do all kinds of side-effect operations (not only logging) while returning the value passed to it. Read https://github.com/raganwald/homoiconic/blob/master/2008-10-29/kestrel.markdown#readme

In Scala the simplest way to implement it is:

  def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }

Then you can define your printing/logging function as:

def logging[A](x: A) = kestrel(x)(println)
def logging[A](s: String, x: A) = kestrel(x){ y => println(s + ": " + y) }

And use it like:

logging(1 + 2) + logging(3 + 4)

your example function becomes a one-liner:

def myFunc() = logging("result is", calcSomeResult())

If you prefer OO notation you can use implicits as shown in other answers, but the problem with such approach is that you’ll create a new object every time you want to log something, which may cause performance degradation if you do it often enough. But for completeness, it looks like this:

implicit def anyToLogging[A](a: A) = new {
  def log = logging(a)
  def log(msg: String) = logging(msg, a)
}

Use it like:

def myFunc() = calcSomeResult().log("result is")

Leave a Comment