Як нова розробка Java вплине на її сумісність з такими мовами, як Scala та Clojure?


11

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

  1. залежать від СВМ та
  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: Наскільки я знаю, Скала 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. Робота над Ламбдасом допомогла виправити ряд невеликих проблем навколо викликів, пов'язаних із динамікою, MethodHandles, MethodReferences тощо. Це означає, що існує ціла низка API-інтерфейсів, які зараз можуть потенційно використовувати інші мови JVM. Які з них вони використовуватимуть за замовчуванням, чи ні, не залежить від них.

Найбільша зміна, що впливає на інтероп, насправді відбулася з Java 7 - із викликаним динамічним байт-кодом, який дозволяє динамічно / пізно прив’язувати дзвінки в JVM - те, що спочатку було розроблено для інших мов JVM. З тих пір він був дуже корисно адаптований для Lamdbas, тому, як для Java 8, Java фактично почне видавати ці байт-коди.

Деякі мови (наприклад, JRuby) вже активно використовують визыванную динаміку, тоді як інші (Scala, Groovy та ін.) Все ще досліджують її використання або знаходяться на ранніх стадіях виправлення. Теоретично це робить їх динамічні дзвінки майже настільки ж ефективними, як і існуючі Java викликає статичні виклики, на відміну від безлічі повільних обходних шляхів, які вони змушені були використовувати в минулому.

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


1
Але, наскільки я знаю, закриття Scala - це предмет.
Джорджіо

1
Так. Скала лише нещодавно відмовилася від підтримки Java 1.5, пройде довго, поки вони не скинуть 1.6.
Йорг W Міттаг

1
@Giorgio Мовні особливості Java не мають наслідків, оскільки більшість з них прирівнюються до хитрощів у байт-коді, коли вони все-таки компілюються. Якщо ми погодимось, що JVM завжди буде сумісним назад, навіть якщо вводяться нові байт-коди, тоді Scala не вплине і може скористатися цими новими функціями JVM у їх зручності.
maple_shaft

1
"Мовні особливості Java є несуттєвими, оскільки більшість з них прирівнюються до хитростей байт-коду при компіляції.": Якщо інша мова хоче використовувати конструкцію Java, вона повинна бути в змозі розпізнати байт-код, сформований для цієї конструкції. Якщо Java вводить нові конструкції, які відображають новий байт-код, мова хоста повинна принаймні реалізувати нову обгортку / інтерфейс для розпізнавання та використання нового байт-коду. Наприклад, якщо лямбда Java 8 не створила об'єкт, а якусь нову конструкцію з новим, специфічним для нього байт-кодом, мова хосту повинна бути адаптована для розпізнавання.
Джорджіо

2
@Giorgio: Звичайно, але таких змін для платформи Java 8 не планується. Фактично, JVMS був розширений лише двічі за всю історію платформи Java, у 2003 та 2010 роках, і вдруге (введення invokedynamicбайт-коду) було спеціально для підтримки інших мов, ніж Java; насправді мова 7 не підтримує та не використовує цей байт-код.
Йорг W Міттаг

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's () => 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, якщо ви або майбутні версії Libary Scala не введете неявну конверсію з цього інтерфейс типу лямбда Scala.
hellodanylo

@SkyDan: Гаразд, тому Скала бачить лямбди Java як об'єкти, що реалізують деякий інтерфейс. Цей момент мені не був зрозумілий: я думав, що Java створить якийсь байт-код, який відрізняється від об'єкта. Але він повинен бути об'єктом під кришкою, інакше він не буде розпізнаний як реалізація інтерфейсу. Я думаю, я зараз це отримав.
Джорджіо

@Giorgio, також якщо ви хочете дізнатися більше про зміни, пов'язані з лямбда в Java 8, і сили, що сприяють цим змінам, рекомендую прочитати цей захоплюючий і детальний огляд проекту Lambda .
hellodanylo

@SkyDan: Читай зараз. Мені здається , що лямбда робити представляють об'єкти (навіть якщо тип / інтерфейс виводиться з контексту , в якому вони визначені). Таким чином, інформація, надана на mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… ("лямбда не є об'єктами") є невірною або, принаймні, оманливою.
Джорджіо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.