简体   繁体   中英

Scala implicit conversion on call-by-name parameter works differently depending on the function is overloaded or not

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM