Как новая разработка Java повлияет на ее совместимость с такими языками, как Scala и Clojure?

11

Насколько я понимаю, и Scala, и Clojure были разработаны как новые языки, которые

  1. зависит от JVM, и
  2. легко интегрируется с кодом Java в том смысле, что они позволяют использовать классы Java внутри кода Scala и Clojure.

Начиная с Java 8 (и, возможно, даже более сильно с последующими версиями Java), будут происходить изменения в семантике языка Java.

Я хотел спросить, как эти изменения повлияют на совместимость между Java и Scala / Clojure и каковы будут последствия. Например, поскольку лямбды в Java 8 не являются объектами (см., Например, здесь ), Scala и Clojure могут иметь дело со значениями Java, которые не являются объектами. Будет ли это проблемой?

Я могу думать о следующих сценариях:

  1. Язык Scala или Clojure будет расширен для адаптации к новой семантике Java (для обработки новых не-объектных значений) и поддержки взаимодействия с Java.
  2. Язык Scala или Clojure не будет расширен. Это будет возможно только в том случае, если новые функции Java, такие как значения функций, могут быть сопоставлены с существующими концепциями. Например, в Scala даже функция - это объект, поэтому я предполагаю, что функции Java снова будут помещены в какие-то объекты, когда они станут видимыми для Scala.
  3. Язык Scala или Clojure будет продолжать поддерживать совместимость вплоть до Java 6 или 7, не следуя последним разработкам Java. Это потребует поддержки старых версий Java (по крайней мере, OpenJDK или другого проекта), чтобы эти языки могли основываться на более консервативной / стабильной ветви Java.

Подводя итог: можем ли мы ожидать, что будущее развитие Java окажет влияние на такие языки, как Scala и Clojure, чтобы обеспечить совместимость с Java? Есть ли какая-либо (ссылка на) текущая дискуссия на эту тему уже?

Запись

Я могу себе представить, что Scala, Clojure и другие языки на основе JVM не будут иметь серьезных проблем при обновлении своей реализации до более новых версий JVM (и что новые функции JVM сделают эту реализацию еще проще). Мой вопрос сосредоточен на особенностях Java как языка и на том, сможет ли / как другой JVM-язык «увидеть» / использовать эти новые функции, а не на том, будут ли языки на основе JVM работать на последних версиях JVM.

Джорджио
источник
6
Неточно сказать, что Scala и т. Д. Зависят от Java. Они зависят от байтового кода JVM. Все функции взаимодействия имеют дело с байт-кодом, а не с исходным кодом языка Java, поэтому любые изменения, внесенные в саму Java, не представляют угрозы. Только изменения, внесенные в JVM, могут повлиять на эти языки, и JVM чрезвычайно консервативна - она ​​в принципе никогда не устраняет поддержку чего-либо. Фактически, большинство изменений в JVM в настоящее время предназначены специально для более новых динамических языков.
Килиан Фот
@Kilian Foth: Насколько я знаю, Scala String- это Java String. Так что Scala использует определенные классы библиотек Java. Но я могу изменить формулировку, если вы думаете, что она слишком сильна.
Джорджио
@Kilian Foth: я убрал термин « зависеть», потому что в центре моего вопроса скорее вопрос взаимодействия между Scala и Java, соответственно. Clojure и Java.
Джорджио
@KilianFoth Это должен быть ответ, потому что он решает основную проблему вопроса. Цель номер один любого нового выпуска Java - обратная совместимость.
maple_shaft
3
@maple_shaft: я исправил свой вопрос и удалил слово «зависит». Как я указывал в другом комментарии, моя проблема не в том, как Scala или Clojure зависят от функций Java или JVM, а в том, как Scala / Clojure может «видеть» функции Java. Насколько я знаю, они могут видеть такие особенности Java 6, как классы, интерфейсы, объекты, методы, примитивные типы данных. Это позволяет Scala / Clojure использовать (вызывать) код Java 6. Мой вопрос заключается в том, смогут ли эти языки «увидеть» (и, следовательно, смогут ли они использовать) будущие языковые конструкции Java или для этого потребуются расширения для языков Scala / Clojure?
Джорджио

Ответы:

15

На самом деле Java 8 не представляет большого вреда для других языков JVM, которые взаимодействуют с Java. Работа, проделанная над Lambdas, помогла исправить ряд небольших проблем, связанных с invokedynamic, MethodHandles, MethodReferences и т. Д., Но, кроме этого, она продолжается как обычно. Тем не менее, существует целый ряд новых API, которые потенциально могут использовать другие языки JVM. Какие из них они будут использовать по умолчанию или нет, зависит от них.

Наибольшее изменение, влияющее на взаимодействие, на самом деле пришло с Java 7 - с помощью вызываемого динамического байт-кода, который допускает динамическое / позднее связывание вызовов в JVM - то, что изначально было разработано для других языков в JVM. С тех пор он был очень полезен для Lamdbas, поэтому, начиная с Java 8, Java фактически начнет испускать эти байт-коды.

Некоторые языки (например, JRuby) уже активно используют invokedynamic, в то время как другие (Scala, Groovy и др.) Все еще изучают его использование или находятся на ранних этапах его исправления. Теоретически это делает их динамические вызовы почти такими же производительными, как и существующие. Java вызывает invokestatic, в отличие от множества медленных обходных путей, которые они вынуждены были использовать в прошлом.

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

Мартейн Вербург
источник
1
Но, насколько я знаю, закрытие Scala - это объект.
Джорджио
1
Ага. Scala только недавно отказалась от поддержки Java 1.5, пройдет много времени, пока они не выпустят 1.6.
Йорг Миттаг,
1
@Giorgio Языковые особенности Java несущественны, так как большинство из них при любых обстоятельствах приравниваются к трюкам с байт-кодом. Если мы примем, что JVM всегда будет обратно совместимым, даже если будут введены новые байт-коды, то Scala не пострадает и может по своему усмотрению воспользоваться этими новыми функциями JVM.
maple_shaft
1
«Языковые особенности Java несущественны, так как большинство из них при любой компиляции приравниваются к трюкам с байт-кодом». Если другой язык хочет использовать Java-конструкцию, он должен иметь возможность распознавать байт-код, сгенерированный для этой конструкции. Если Java вводит новые конструкции, которые отображаются на новый байт-код, язык хоста должен по крайней мере реализовать новую оболочку / интерфейс для распознавания и использования нового байт-кода. Например, если лямбда-версия Java 8 не создала объект, а какую-то новую конструкцию с новым, конкретным для него байт-кодом, язык хоста должен быть адаптирован для его распознавания.
Джорджио
2
@ Джорджио: Конечно, но такие изменения не запланированы для платформы Java 8. Фактически, JVMS расширялась только дважды за всю историю платформы Java, в 2003 и 2010 годах, и второй раз (введение invokedynamicбайт-кода) был специально для поддержки языков, отличных от Java; на самом деле язык Java 7 не поддерживает и не использует этот байт-код.
Йорг Миттаг
2

Scala собирается остаться позади, когда Java добавляет лямбды, потому что лямбды Java получают тип в соответствии с контекстом, в котором они используются, тогда как лямбды Scala получают тип на основе их арности, типов параметров и возвращаемых типов, например,

executor.execute(() -> { System.out.println("hello world"); });

из Java 8 можно записать в Scala как:

executor execute new Runnable {
    override def run() { println("hello world") }
}

если вы не используете / не пишете некоторые обертки, конвертирующие Scala () => Unit в Runnable.

Рики Кларксон
источник
Спасибо за ответ, а также за решение моего вопроса (+1). Если я правильно понимаю, Scala придется продолжать использовать анонимные классы для создания экземпляров интерфейсов в контексте, в котором Java 8 будет использовать лямбды (потому что лямбды Java 8 имеют другую семантику, чем лямбды Scala). Еще один момент, который мне не ясен, это то, что произойдет, если метод Java вернет лямбда-код Java. Что происходит, если класс Scala вызывает этот метод? Какой тип возврата будет в Scala?
Джорджио
1
@Giorgio В Java 8 лямбда-выражение представляет собой ярлык на уровне языка для создания экземпляра интерфейса, который объявляет один метод и который откладывается в контексте. Поэтому, когда метод Java 8 возвращает лямбду, он фактически возвращает экземпляр интерфейса, который объявлен как тип возврата метода. Начиная с Scala 2.9.1, тип возвращаемого значения будет просто экземпляром некоторого интерфейса, скажем (Runnable или Comparator), который вы не можете рассматривать как лямбду Scala, если только вы или будущие выпуски библиотеки Scala не представите неявное преобразование из этого. интерфейс к лямбда-типу Scala.
hellodanylo
@SkyDan: Хорошо, поэтому Scala будет видеть лямбды Java как объекты, реализующие некоторый интерфейс. Этот момент мне не был ясен: я думал, что Java сгенерирует некоторый байт-код, который отличается от кода объекта. Но это должен быть объект под капотом, иначе он не будет признан реализацией интерфейса. Я думаю, что получил это сейчас.
Джорджио
@Giorgio, также, если вы хотите узнать больше об изменениях, связанных с лямбдой в Java 8, и о силах, которые управляют этими изменениями, я рекомендую вам прочитать этот увлекательный и подробный обзор проекта Lambda .
hellodanylo
@SkyDan: сейчас читаю. Мне кажется , что лямбды делать представляют объекты (даже если тип / интерфейс выводится из контекста , в котором они определены). Таким образом, информация, предоставленная на mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… («лямбды не являются объектами»), неверна или, по крайней мере, вводит в заблуждение.
Джорджио