Richard Searle

home

Surprises with call-by-name and unary functions

27 Mar 2012

I recently created a subtle defect while using the Play2 enumerators Both  pushee and fromCallback are passed an onComplete that is executed when the target Iteratee can no longer accept any input. The signatures are slightly different
pushee:onComplete: ⇒ Unit
fromCallback:onComplete: () ⇒ Unit
I did not notice the difference and used {() => println("completed")} in each case. That prints the expected output for fromCallback but is not executed for pushee. The compiler does not generate any errors, making this a completely silent failure. Thanks to sadek for pointing out my error. The next step was to gain a better understanding of this corner of the Scala language
def f(a: => Unit){a}
def g(a:() => Unit){a()}
def h(a: => String)={a}
def i(a:() => String)={a()}

f{println("1")}
f{() => println("2")}
g{() => println("3")}
println(h{"5"})
println(h{()=>"6"})
println(i{() => "7"})
The result is 1 3 5 :9: error: type mismatch; found : () => java.lang.String required: String println(h{()=>"6"}) ^ 7 So there is something special about () => Unit