Можно ли считать "вызов по имени" в Scala синтаксическим сахаром API функционального интерфейса Java8?

Пример Scala "call be name":def giveMeName(b: => String)

javap результат:

public class some.package.CallByNameEx { public void giveMeName(scala.Function0<java.lang.String>); public some.package.CallByNameEx(); }

Пример API функционального интерфейса Java:void giveMeName(Supplier<String> b)

javap результат:

public class some.package.SupplyEx { public some.package.SupplyEx(); void giveMeName(java.util.function.Supplier<java.lang.String>); }

Есть ли существенная разница в том, как они оцениваются внутренне, учитывая javap Результат обоих приведенных выше случаев был практически одинаковым

Согласно моему нынешнему пониманию, они оба используют замыкания и лениво оценивают выражение. Пожалуйста, поправьте меня, если понимание неверно.

2 ответа

Вы правильно поняли, call-by-name синтаксис в значительной степени является сокращением, позволяющим вам избежать дополнительной бюрократии, связанной с передачей Function0 вокруг.


Внутренне b: => String будет представлен Function0 - как b: () => String было бы.

Разница в том, что с помощью call-by-name, вы можете просто игнорировать детали реализации использования Function0,

Посмотрим, как это будет выглядеть с b: () => String:

def giveMeName(b: () => String): String = b.apply()

и то же самое снова с помощью call-by-name:

def giveMeName(b: => String): String = b

Обратите внимание на то, как красиво шаблон apply() звонка можно избежать.

Таким образом, это синтаксический сахар, но не для функциональных интерфейсов Java, а для нативного Scala Function0

Я написал немного больше об этом здесь: http://4comprehension.com/leveraging-lambda-expressions-for-lazy-evaluation-in-java/

Можно ли считать это синтаксическим сахаром? Да, возможно. API функционального интерфейса Java8? Нет.

Давайте перейдем к определению в http://wiki.c2.com/?SyntacticSugar:

Функции, добавленные в язык или другой формализм, чтобы сделать его более приятным для людей, но которые не влияют на выразительность формализма (сравните хром). Используется ESP. когда есть очевидный и тривиальный перевод сахарного признака в другие конструкции, уже присутствующие в обозначениях.

Таким образом, функции Scala могут быть синтаксическим сахаром только для других функций Scala, но не для Java. В этом случае, def giveMeName(b: => String) переводится что-то вроде в def giveMeName(b: () => String), "Возможно" часть заключается в том, что перевода декларации недостаточно: необходимо также перевести все вызовы, а метод помечен, чтобы вы не могли передать что-то типа () => String в def giveMeName(b: => String),

Есть ли существенное различие в том, как они оцениваются внутренне, учитывая, что результаты javap в обоих вышеупомянутых случаях были практически идентичными

В результате вы показываете, что нечего оценивать, и они все равно будут "почти идентичными", если вы замените Supplier<String> от List<String>, Означает ли это, что вызов по имени является синтаксическим сахаром для List? Конечно, нет.

Но Скала () => String семантически эквивалентно Supplier<String> (это не то, что вы можете увидеть из javap), и потому что => String эквивалентно () => String

они оба используют замыкания и лениво оценивают выражение

Если "они" - это API-интерфейсы, которые вы показываете, нет, ни сами не используйте замыкания. Вы можете передавать замыкания обоим (или не замыканиям).

Другие вопросы по тегам