Let's see the code below:
import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
def bar(foo: Boolean) = {}
bar {
println("Hello")
64
}
This code does not print anything, because the block contains println("Hello")
treated as => Int
and it is converted to Foo
by int2Foo
. But the surprising thing is happen if we omit the overloaded function bar(foo: Boolean)
import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
bar {
println("Hello")
64
}
This prints Hello
because it evaluates the block, and only the last statement, 64
in this case, is treated as a call-by-name parameter. I cannot understand what kind of rationale exists behind of this difference.
I think the Scala specification is ambiguous about how implicit views should be applied here. In other words, both of the following interpretations of the statement conform to the spec:
bar { println("Hello"); int2Foo(64) }
bar { int2Foo({ println("Hello"); 64 }) }
Of course, it is extremely counterintuitive for an unrelated overload to affect this behavior. It seems to me that the behavior, although ambiguous, should at least be consistent. This must be an implementation detail of the compiler interactions between overload resolution, by-name parameters, and implicit views. I have filed SI-9386 to address the issue.
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