O ile rozumiem, zarówno Scala, jak i Clojure zostały zaprojektowane jako nowe języki, które
- zależą od JVM i
- łatwo integrują się z kodem Java w tym sensie, że pozwalają na korzystanie z klas Java wewnątrz kodu Scala i Clojure.
Począwszy od Java 8 (a może jeszcze mocniej w kolejnych wersjach Java), nastąpią zmiany w semantyce języka Java.
Chciałem zapytać, jak te zmiany wpłyną na interoperacyjność między Javą a Scalą / Clojure i jakie będą tego konsekwencje. Na przykład, ponieważ lambdy w Javie 8 nie są obiektami (patrz np. Tutaj ), Scala i Clojure mogą mieć do czynienia z wartościami Java, które nie są obiektami. Czy to byłby problem?
Mogę wymyślić następujące scenariusze:
- Język Scala lub Clojure zostanie rozszerzony w celu dostosowania do nowej semantyki Java (w celu obsługi nowych wartości niebędących obiektami) i obsługi interoperacyjności z Javą.
- Język Scala lub Clojure nie zostanie przedłużony. Byłoby to możliwe tylko wtedy, gdyby nowe funkcje Java, takie jak wartości funkcji, można było odwzorować na istniejące pojęcia. Np. W Scali nawet funkcja jest obiektem, więc sądzę, że funkcje Java byłyby ponownie zawinięte w jakieś obiekty, gdy staną się widoczne dla Scali.
- Język Scala lub Clojure będzie nadal obsługiwał interoperacyjność do wersji Java 6 lub 7, bez śledzenia najnowszych osiągnięć Javy. Wymagałoby to, aby starsze wersje Java były nadal obsługiwane (przynajmniej przez OpenJDK lub inny projekt), aby te języki mogły być oparte na bardziej konserwatywnej / stabilnej gałęzi Java.
Podsumowując: czy możemy oczekiwać, że przyszły rozwój Java będzie miał wpływ na języki takie jak Scala i Clojure, aby zachować interoperacyjność z Javą? Czy jest już jakaś (prowadząca do) dyskusja na ten temat?
Uwaga
Mogę sobie wyobrazić, że Scala, Clojure i inne języki oparte na JVM nie będą miały większych problemów z aktualizacją ich implementacji do nowszych wersji JVM (i że nowe funkcje JVM jeszcze bardziej ułatwią tę implementację). Moje pytanie dotyczy funkcji Java jako języka i tego, czy / jak inny język JVM będzie w stanie „zobaczyć” / korzystać z tych nowych funkcji, a nie tego, czy języki oparte na JVM będą działały na najnowszych JVM.
String
to JavaString
. Dlatego Scala używa pewnych klas bibliotek Java. Ale mogę zmienić sformułowanie, jeśli uważasz, że jest zbyt silny.Odpowiedzi:
W rzeczywistości Java 8 nie wprowadza wiele, co byłoby szkodliwe dla innych języków JVM współpracujących z Javą. Prace wykonane w Lambdas pomogły rozwiązać wiele drobnych problemów związanych z wywoływanymi dynamicznymi, MethodHandles, MethodReferences itd. - ale poza tym jest to normalne. To powiedziawszy, istnieje zupełnie nowa grupa interfejsów API, do których potencjalnie mogłyby teraz zadzwonić inne języki JVM. To, które będą używać domyślnie, czy nie, zależy od nich.
Największa zmiana mająca wpływ na interop faktycznie pojawiła się w Javie 7 - z wywoływanym dynamicznym kodem bajtowym, który umożliwia dynamiczne / późne wiązanie wywołań w JVM - coś, co początkowo zostało zaprojektowane dla innych języków JVM. Od tego czasu został bardzo użytecznie dostosowany do Lamdbas, więc od Java 8 Java zacznie emitować te kody bajtowe.
Niektóre języki (na przykład JRuby) już intensywnie używają invokedynamic, podczas gdy inne (Scala, Groovy i in.) Wciąż badają jego użycie lub są na wczesnych etapach łatania go. Teoretycznie sprawia, że ich dynamiczne wywołania są prawie tak wydajne jak istniejące Wywołania invokestatic Java, w przeciwieństwie do niezliczonej liczby wolniejszych obejść, których musieli używać w przeszłości.
Java 9 przyniesie więcej wyzwań dla języków JVM wraz z projektem Jigsaw wchodzącym na platformę, która będzie początkiem końca tradycyjnego ładowania klas i ścieżek klas dla JVM. Ludzie języka JVM są tego świadomi i oczekuję rozsądnej współpracy.
źródło
invokedynamic
kodu bajtowego) był specjalnie przeznaczony do obsługi języków innych niż Java; w rzeczywistości język Java 7 nie obsługuje tego kodu bajtowego ani go nie używa.Scala ma zamiar pozostać w tyle, gdy Java dodaje lambdy, ponieważ lambdom Java przypisuje się typ zgodnie z kontekstem, w którym są używane, podczas gdy Scala lambdom przypisuje się typ na podstawie ich arancji, typów parametrów i typów zwracanych, więc np.
z Java 8 można zapisać w Scali jako:
chyba że użyjesz / napiszesz jakieś opakowania konwertujące Scala's () => Unit na Runnable.
źródło