Почему стирание усложняет реализацию типов функций? - PullRequest
11 голосов
/ 15 сентября 2011

Я прочитал из интервью с Нилом Гафтером :

«Например, добавить типы функций в язык программирования гораздо сложнее с Erasure как частью Generics».

РЕДАКТИРОВАТЬ: Другое место, где я встречал подобное утверждение, было в сообщении Брайана Гетца в списке рассылки Lambda Dev , где он говорит, что с лямбдами легче обращаться, когда они простоанонимные классы с синтаксическим сахаром:

Но я возражал против типов функций не потому, что я не люблю типы функций - я люблю типы функций - но эти типы функций плохо боролись с существующим аспектомсистема типов Java, стирание.Стираемые типы функций являются худшими из обоих миров.Итак, мы удалили это из дизайна.

Может кто-нибудь объяснить эти утверждения?Зачем мне нужна информация о типе среды выполнения с лямбдами?

Ответы [ 4 ]

6 голосов
/ 16 сентября 2011

Насколько я понимаю, они решили, что из-за стирания было бы грязно идти по пути типов функций , например. делегаты в C #, и они могут использовать только лямбда-выражения , что является просто упрощением единственного абстрактного метода синтаксиса класса.

Делегаты в C #:

public delegate void DoSomethingDelegate(Object param1, Object param2);
...
//now assign some method to the function type variable (delegate)
DoSomethingDelegate f = DoSomething;
f(new Object(), new Object());

(другой образец здесь http://geekswithblogs.net/joycsharp/archive/2008/02/15/simple-c-delegate-sample.aspx)

Один аргумент, который они выдвинули в Project Lambda docs:

Стираются общие типы, которые открывают дополнительные места, где разработчики подвергаются стиранию. Например, это не будет возможно перегрузить методы m (T-> U) и m (X-> Y), что будет запутанный.

раздел 2 в: http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html

(Окончательный синтаксис лямбда-выражений будет немного отличаться от приведенного выше документа: http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html)

(x, y) => { System.out.printf("%d + %d = %d%n", x, y, x+y); }

В общем, мое лучшее понимание - то, что только часть синтаксического материала, который мог бы, фактически использоваться. Скорее всего, Нил Гафтер имел в виду, что невозможность использования делегатов усложнит адаптацию стандартных API к функциональному стилю, а будет сложнее выполнить обновление javac / JVM.

Если кто-то понимает это лучше меня, я буду рад прочитать его рассказ.

2 голосов
/ 25 декабря 2011

Гетц расширяет рассуждения в Состояние лямбды 4-е изд. :

Альтернативный (или дополнительный) подход к типам функций, предложенный некоторыми ранними предложениями, будетбыло ввести новый, структурный тип функции.Тип типа «функция из String и Object в int» может быть выражен как (String, Object) -> int.Эта идея была рассмотрена и отвергнута, по крайней мере, на данный момент, из-за нескольких недостатков:

  • Это усложнит систему типов и дополнительно смешает структурные и номинальные типы.
  • приводить к расхождению стилей библиотек - некоторые библиотеки будут продолжать использовать интерфейсы обратного вызова, в то время как другие будут использовать структурные типы функций.
  • Синтаксис может быть непривлекательным, особенно если включены проверенные исключения.
  • Маловероятно, что для каждого отдельного типа функции будет представление во время выполнения, а это означает, что разработчики будут подвергаться и ограничиваться стиранием.Например, было бы невозможно (возможно удивительно) перегрузить методы m (T-> U) и m (X-> Y).

Итак, вместо этого мы выбрали путь«использовать то, что вы знаете» - поскольку существующие библиотеки широко используют функциональные интерфейсы, мы систематизируем и используем этот шаблон.

Чтобы проиллюстрировать, вот некоторые из функциональных интерфейсов в Java SE 7, которые хорошо подходят дляиспользуется с новыми языковыми функциями;следующие примеры иллюстрируют использование нескольких из них.

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.util.Компаратор
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener
  • ...

Обратите внимание, что стирание является лишь одним из соображений.В целом, лямбда-подход Java отличается от Scala не только в типизированном вопросе.Это очень Java-ориентированный.

1 голос
/ 16 сентября 2011

Может быть потому, что вам действительно нужен тип Function<R, P...>, параметризованный с возвращаемым типом и некоторой последовательностью типов параметров.Но из-за стирания вы не можете иметь такую ​​конструкцию, как P..., потому что она может превратиться только в Object[], что слишком свободно для использования во время выполнения.

Это чистое предположение.Я не теоретик типов;я даже не играл ни одного по телевизору.

0 голосов
/ 16 сентября 2011

Я думаю, что он имеет в виду в этом утверждении, что во время выполнения Java не может определить разницу между этими двумя определениями функций:

void doIt(List<String> strings) {...}
void doIt(List<Integer> ints) {...}

Поскольку во время компиляции информация о том, какие типы данных содержит списокстерта, поэтому среда выполнения не сможет определить, какую функцию вы хотите вызвать.

Попытка скомпилировать оба этих метода в одном классе вызовет следующее исключение:

doIt(List<String>) clashes with doIt(List<Integer); both methods have the same erasure
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...