I'm trying to understand what by-name type annotations mean in the context of higher-order functions. Here's an example:
object Test {
def apply[A, B](f: (=> A) => B, x: => A): B = f(x)
def const[A](ignored: A): Int = 1
val res: Int = apply(const, ???)
}
const
is strict in its argument (i.e. it lacks a =>
annotation), so why isn't it forcing its argument (which is ???
in this case) and raises an exception?
Is there a paper describing the semantics here?
I'm looking for an authoritative answer here.
The argument f
in your apply
function is a Funcion1
which takes a call-by-name parameter of type A
and returns a B
. Therefore, f(x)
will not evaluate the call-by-name parameter x
, but pass its reference directly to f
.
It is helpful to understand res
as follows:
def res[C]: Int = apply[C, Int](const, ???)
where in your example C
would be an unspecific type. Now what is the type parameter inferred for const
in this line? It is => C
. Unfortunately you cannot type that parameter:
def res[C]: Int = apply[C, Int](const[=> C], ???) // illegal syntax
But you can verify what is going on:
def res[C]: Int = apply[C, Int](const[Nothing], ???)
giving you
<console>:10: error: type mismatch;
found : Nothing => Int
required: => C => Int
def res[C]: Int = apply[C, Int](const[Nothing], ???)
^
This type appears inside const
as a Function0[Int]
(so Scala implicitly treats call-by-name or "thunk" arguments as a function with no arguments). Again you can verify this:
def const[A](ignored: A): Int = if (ignored.isInstanceOf[Function0[_]]) 1 else 0
Now Test.res
will give you 1
(meaning that ignored
is indeed a Function0
).
So to answer the question a different way, const
has an eager argument of type A
, but that doesn't matter here because A
becomes a function in your example, and you never apply that function, therefore ???
is never executed.
There is some debate as to why there is both a "thunk" or parentheses-less function and an empty-paren function (Function0
) in Scala.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With