openjdk.ruOpenJDK на русском

JEP 126: Lambda Expressions & Virtual Extension Methods

Лямбда-выражения и virtual extension methods

АвторJoseph D. Darcy
ОтветственныйBrian Goetz
ТипFeature
ОбластьSE
СтатусClosed / Delivered
Выпуск8
Компонентtools / javac
JSRs269 MR, 335
Обсуждениеlambda dash dev at openjdk dot java dot net
ТрудоёмкостьXL
ДлительностьXL
БлокируетJEP 101: Generalized Target-Type Inference
JEP 107: Bulk Data Operations for Collections
JEP 109: Enhance Core Libraries with Lambda
JEP 155: Concurrency Updates
РецензентыBrian Goetz
ОдобренBrian Goetz
Создан2011/11/01 20:00
Обновлён2015/01/09 17:52
Задача8046116

Аннотация

Добавить в язык программирования Java и платформу лямбда-выражения (замыкания) и сопутствующие возможности, включая ссылки на методы, улучшенный вывод типов и virtual extension methods (виртуальные методы расширения).

Цели

Основные возможности — лямбда-выражения и virtual extension methods — вместе с набором второстепенных сопутствующих возможностей служат нескольким целям платформы:

  • Упростить создание и использование более абстрактных и более производительных библиотек
  • Обеспечить более плавное развитие библиотек с сохранением совместимости при миграции

Лямбда-выражения не только добавляют в язык программирования Java ставшую уже распространённой возможность, но и открывают путь к улучшенной поддержке многоядерных систем, так как делают возможными идиомы внутренней итерации.

К сопутствующим возможностям языка, связанным с лямбда-выражениями, относятся virtual extension methods, которые позволят развивать интерфейсы с сохранением совместимости по исходному и по двоичному коду.

Помимо изменений в языке, будут также внесены согласованные изменения в библиотеки и в JVM.

Обратите внимание: действующий и продолжающийся проект OpenJDK Project Lambda появился раньше процесса JEP, как и соответствующий JSR, JSR 335, который запланирован для Java SE 8 (JSR 336).

Что не является целью

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

Мотивация

Многие другие широко используемые объектно-ориентированные языки программирования, в том числе работающие на JVM (например, Groovy, Ruby и Scala) и на других виртуальных машинах (C# на CLR), поддерживают замыкания. Поэтому Java-программисты всё лучше знакомы с этой возможностью языка и с моделями программирования, которые она делает возможными.

Особый интерес представляет поддержка идиомы внутренней итерации. Массивы и коллекции сейчас поддерживают внешнюю итерацию, при которой логика управления итерацией находится вне обходимой структуры данных. Например, цикл for-each по массиву или коллекции — пример внешней итерации. Семантика цикла for в Java предписывает строго последовательную итерацию, а значит, единственный доступный программисту способ обхода стандартной коллекции не позволяет задействовать все доступные ядра.

При внутренней итерации структуре данных передаётся фрагмент кода для выполнения в виде лямбда-выражения, и структура данных сама отвечает за разбиение вычисления и выдачу результатов. Поскольку структуре данных известны её собственные внутренние детали, она потенциально может выбрать лучшее планирование вычисления, настраивая такие параметры, как

  • Другой порядок выполнения
  • Конкурентное выполнение с помощью пулов потоков
  • Параллельное выполнение с помощью разбиения и захвата работы (work stealing). Фреймворк fork/join, добавленный в Java SE 7, — один из таких фреймворков-кандидатов для параллельного выполнения; он обеспечивает устойчиво производительное разбиение работы для широкого диапазона числа ядер.

Типичный пример стиля внутренней итерации — последовательность операций filter-map-reduce, например:

int maxFooWeight =
    collection.filter( /* isFoo Predicate as a lambda */)
              .map(    /* Map a Foo to its weight with a lambda */)
              .max();  /* Reduction step */

Лямбда-выражения — это выражения с кратким синтаксисом для представления нужной операции. Этот стиль заменяет один или несколько явных циклов for, которые без необходимости ограничивали бы порядок обхода коллекции. Кроме того, хорошо спроектированный алгоритм может не только выполнять такие наборы операций параллельно, но и объединить три операции в один параллельный проход.

Project Lambda также включает virtual extension methods, которые устранят давнее ограничение: невозможность добавлять методы в широко используемые интерфейсы из-за проблем с совместимостью по исходному коду.

Если добавить методы расширения в существующие интерфейсы коллекций, такие как java.util.Collection и java.util.List, существующие реализации этих типов смогут участвовать в новой идиоме программирования. Реализации этих типов — в JDK и в других местах — могут переопределять реализации методов расширения по умолчанию из суперинтерфейсов, чтобы предоставить более производительные или иным образом специализированные реализации.

Описание

Самая актуальная информация о деталях работы находится на развивающейся странице проекта OpenJDK Project Lambda и на странице соответствующего JSR.

Работа над Project Lambda в целом затрагивает следующие компоненты платформы:

  • Спецификация языка программирования Java
  • Спецификация виртуальной машины Java
  • Эталонная реализация изменений языка в javac
  • Изменения формата class-файлов для поддержки компиляции лямбда-выражений и virtual extension methods
  • (Возможно) улучшения JVM для более эффективного выполнения лямбда-выражений
  • Изменения JVM для поддержки virtual extension methods
  • Изменения базовых API для добавления virtual extension methods
  • Изменения базовых API для поддержки использования лямбда-выражений
  • Обновления библиотек JDK для использования новых методов расширения
  • Обновления API рефлексии, таких как базовая рефлексия и javax.lang.model, чтобы они предоставляли информацию, связанную с лямбда-выражениями и методами расширения
  • Обновления инструментов для работы с class-файлами, таких как javap и pack200/unpack200, чтобы они понимали новые атрибуты JVM
  • (Возможно) обновления сериализации, включая сериализацию IIOP
  • Улучшения javadoc, чтобы указывать, какие интерфейсы можно использовать для лямбда-выражений
  • Поддержка во время выполнения в java.lang.* для трансляции лямбда-выражений и virtual extension methods

Альтернативы

Project Lambda начался с предварительного (straw-man) предложения и прошёл несколько итераций «State of the Lambda», в ходе которых менялись и синтаксис, и набор возможностей проекта.

Работа над лямбда-выражениями в рамках Project Lambda опирается на многочисленные предыдущие проекты, в том числе, но не только:

Набор возможностей Project Lambda признан более отвечающим потребностям развития платформы Java, чем более ранние предложения.

Дизайн virtual extension methods также опирается на большой объём предшествующих работ в сообществе языков программирования, в том числе:

По сравнению с другими языковыми средами у языка Java всегда была гораздо более предсказуемая семантика: встроенные примитивные типы имеют известный размер, исключения выбрасываются в точно определённых местах, порядок вычисления выражений точно определён и так далее. Ослабление семантики встроенных циклов for и while ради попыток автоматического распараллеливания было признано нежелательным и недостаточным для достижения целей поддержки многоядерных систем.

Тестирование

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

Полезность возможности будет также проверена её использованием в библиотеках платформы JDK.

Риски и допущения

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

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

Зависимости

Предпочтительный на данный момент подход к реализации лямбда-выражений опирается на invokedynamic и дескрипторы методов (method handles), введённые в JSR 292. Поэтому приемлемая производительность лямбда-выражений зависит, среди прочего, от приемлемой производительности дескрипторов методов.

Ожидается обратная связь между работой над библиотеками (JEP 107 и 109) и возможностями языка.

Влияние

  • Другие компоненты JDK: влияние на другие компоненты JDK описано в разделе «Описание».
  • Совместимость: virtual extension methods предназначены для того, чтобы интерфейсы можно было развивать с сохранением совместимости по исходному коду.add virtual extension methods
  • Безопасность: потребуется проверка безопасности отдельных аспектов реализации лямбда-выражений во время выполнения.
  • Производительность и масштабируемость: следует отслеживать производительность идиом, рассчитанных на лямбда-выражения, по сравнению с традиционными идиомами.
  • Документация: необходимо написать руководства пользователя и сопутствующую документацию.
  • TCK: поскольку это крупная возможность платформы, необходимо разработать TCK для языка и библиотек.