scalalazy-evaluationscalac

Is there any help for lazy argument passing in Scala?


It could sound like a rookie mistake but I do a lot of that. While passing lazy evaluated block or value into a function, if I forget somehow make that function's corresponding parameter lazy (pass/call by name) its causing some confusions at first glance because it forces evaluation.Very small ex;

lazy val a = {println("a");1}
def myfunc(b:Int){println("hello")}
myfunc(a);

Output:

a
Hello

So my question, is there any compiler help for this problem?(flag etc.) Or this is a kind of thing that I should take care of ?


Solution

  • You can move the problem into type system.

    1. Don't use lazy vals explicitly, instead...
    2. Define a box for lazily evaluated values:

    class Lazy[A](body: => A) {
      lazy val value = body
    }
    
    object Lazy {
      def apply[A](body: => A) = new Lazy[A](body)
    }
    

    Now you will have a little bit of help from the compiler:

    val a = Lazy {
      println("a")
      1
    }
    
    def myfunc(b: Lazy[Int]) = {
      println("hello")
    }
    
    myfunc(a) // ok, and it doesn't print "a" since it never uses it
    // myfunc(42) // won't compile
    
    def myfunc2(b: Int) = b + 42
    
    // myfunc2(a) // does not compile
    myfunc2(a.value) // ok, explicitly evaluate - or consider refactoring myfunc2