Совместимость между замыканиями Scala и замыканиями Java 8 - PullRequest
24 голосов
/ 15 июня 2010

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

Учитывая, чтоЗамыкания Scala гораздо более мощные, чем замыкания, запланированные для Java 8. Интересно, можно ли будет, например, вызвать метод Java, взяв замыкание из Scala, определив замыкание в Java и передав его функции Scala и т. Д .?

Так будут ли Java-замыкания представлены как их аналоги в Scala в байт-коде или по-другому?Удастся ли сократить разрыв функциональности между замыканиями Java / Scala?

Ответы [ 3 ]

15 голосов
/ 04 августа 2010

Я думаю, что это сложнее, чем предполагать, что здесь есть две группы заинтересованных сторон. Люди Project Lambda , кажется, работают в основном независимо от людей Oracle, время от времени бросают что-то через стену , что люди Project Lambda обнаруживают косвенно. (Scala, конечно, третий участник.)

Так как последнее предложение Project Lambda состоит в том, чтобы полностью исключить типы функций и просто создать какой-то причудливый вывод для реализации интерфейсов, которые имеют единственный метод astract ( SAM типы) Я предвижу следующее:

  • Вызов кода Scala, который требует закрытия Scala, будет полностью зависеть от реализации признаков Function* (и реализации признаков в целом) - будет ли он представлен компилятору Java как SAM (который он находится в Scala-land) или неабстрактные методы также кажутся абстрактными для JVM. (Я думаю, что в настоящее время они выглядят абстрактно, поскольку черты реализованы в виде интерфейсов, но я почти ничего не знаю о реализации Scala. Это может стать серьезным препятствием для взаимодействия.)

    Осложнения с помощью универсальных Java-выражений (в частности, как выразить Int / int / Integer или Unit / Nothing / void в универсальном интерфейсе) также могут усложнять ситуацию.

  • Использование функций Scala для реализации Java SAM не будет отличаться от того, что есть сейчас - вам нужно создать implicit преобразование для конкретного интерфейса, который вы хотите реализовать.

Если JVM получает типы функций (а Oracle, похоже, не исключил эту возможность), это может зависеть от того, как она реализована. Если они являются объектами первого класса, реализующими определенный интерфейс, то все, что нужно Scala для совместимости, - это заставить Function* реализовать новый интерфейс. Если новый тип типа полностью реализован в JVM, это может быть сложно - разработчики Scala могут обернуть их, используя магию, как они это делают в настоящее время для Array с, или они могут создавать преобразования implicit. (Новая концепция языка кажется немного надуманной.)

Я надеюсь, что одним из результатов всего этого обсуждения будет то, что все различных языков JVM согласятся на какой-то стандартный способ представления замыканий - так что Scala, Groovy, JRuby и т. Д. ... все могут проходить замыкания назад и вперед с минимальными трудностями.

Что меня интересует, так это предложения виртуальных методов расширения , которые позволят API-интерфейсам Java Collections использовать лямбды-выражения. В зависимости от того, как они реализованы, они могут значительно упростить некоторые проблемы двоичной совместимости, с которыми нам приходилось сталкиваться при изменении кода Scala, и могут помочь более легко и эффективно реализовать черты.

Я надеюсь, что некоторые разработчики Scala будут вовлечены и предложат свой вклад, но на самом деле я не видел ни обсуждения Scala в списках Project Lambda, ни каких-либо участников, которые бы говорили о мне как о разработчиках Scala.

7 голосов
/ 15 июня 2010

Вы, вероятно, сможете сделать это чрезвычайно легко, используя неявные преобразования а-ля collection.JavaConversions вне зависимости от того, поступают они из коробки или нет.

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

2 голосов
/ 30 марта 2016

Примечание: 5 лет спустя, SCALA 2.12.0-M3 (октябрь 2015 г.) включил это улучшение:

Scala 2.12 испускает замыкания в том жестиль как Java 8 .

Для каждой лямбды компилятор генерирует метод, содержащий лямбда-тело.
Во время выполнения этот метод передается в качестве аргумента LambdaMetaFactory, предоставленного JDK,который создает объект замыкания.

По сравнению со Scala 2.11, новая схема имеет то преимущество, что компилятор больше не генерирует анонимный класс для каждой лямбды.Это приводит к значительно меньшим JAR-файлам.

...