Неявное преобразование Scala для параметра вызова по имени работает по-разному в зависимости от того, перегружена функция или нет.

Давайте посмотрим код ниже:

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
}

Этот код ничего не печатает, потому что блок содержит println("Hello"), обработанный как => Int, и он преобразуется в Foo с помощью int2Foo. Но что удивительно, если мы опустим перегруженную функцию 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
}

Это печатает Hello, потому что он оценивает блок, и только последний оператор, 64 в данном случае, обрабатывается как параметр вызова по имени. Я не могу понять, какое обоснование стоит за этой разницей.


person pocorall    schedule 07.07.2015    source источник
comment
Связанная проблема: issues.scala-lang.org/browse/SI-3237   -  person Ben Reich    schedule 07.07.2015
comment
Такое поведение никоим образом не предназначено, если только я что-то не упустил. Даже если он соответствует спецификации, он крайне нелогичен и подвержен серьезным ошибкам (например, что, если кто-то удалит перегрузку, которая явно нигде не используется, что приведет к тому, что параметр по имени будет вести себя по-другому).   -  person Ben Reich    schedule 07.07.2015
comment
Обертывание блока в {...}:Int также меняет поведение.   -  person Ben Reich    schedule 07.07.2015


Ответы (1)


Я думаю, что спецификация Scala неоднозначно относится к тому, как здесь следует применять неявные представления. Другими словами, обе следующие интерпретации утверждения соответствуют спецификации:

bar { println("Hello"); int2Foo(64) }
bar { int2Foo({ println("Hello"); 64 }) }

Конечно, крайне нелогично, чтобы несвязанная перегрузка влияла на такое поведение. Мне кажется, что поведение хоть и неоднозначное, но как минимум должно быть последовательным. Это должна быть деталь реализации взаимодействий компилятора между разрешением перегрузки, параметрами по имени и неявными представлениями. Я отправил SI-9386 для решения проблемы.

person Ben Reich    schedule 08.07.2015