Подтвердить что ты не робот

Совместимость между закрытием Scala и закрытием Java 8

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Поскольку последнее предложение проекта 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 s, или могут создавать преобразования implicit. (Новая концепция языка кажется немного надуманной.)

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

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

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

Ответ 3

Скорее всего, вы сможете сделать это очень легко, используя неявные преобразования a la collection.JavaConversions независимо от того, выходят ли они из коробки.

Конечно, это не так, потому что это может быть так, что замыкания Java превращаются в типы, которые генерируются JVM во время выполнения - я, кажется, вспоминаю презентацию Neal Gafter, говорящую что-то в этих строках