Bagaimana perkembangan baru Jawa akan mempengaruhi interoperabilitasnya dengan bahasa seperti Scala dan Clojure?

11

Sejauh yang saya mengerti, baik Scala dan Clojure telah dirancang sebagai bahasa baru itu

  1. tergantung pada JVM, dan
  2. mudah diintegrasikan dengan kode Java, dalam arti bahwa mereka memungkinkan untuk menggunakan kelas Java di dalam kode Scala dan Clojure.

Dimulai dengan Java 8 (dan mungkin bahkan lebih kuat dengan versi Java berikutnya), akan ada perubahan dalam semantik bahasa Java.

Saya ingin bertanya bagaimana perubahan ini akan berdampak pada interoperabilitas antara Jawa dan Scala / Clojure dan apa konsekuensinya. Misalnya, karena lambdas di Java 8 bukan objek (lihat misalnya di sini ), Scala dan Clojure mungkin harus berurusan dengan nilai-nilai Java yang bukan objek. Apakah ini akan menjadi masalah?

Saya dapat memikirkan skenario berikut:

  1. Bahasa Scala atau Clojure akan diperluas untuk beradaptasi dengan semantik Java baru (untuk menangani nilai-nilai non-objek baru) dan mendukung interoperabilitas dengan Java.
  2. Bahasa Scala atau Clojure tidak akan diperpanjang. Ini hanya akan mungkin jika fitur Java baru seperti nilai fungsi dapat dipetakan ke konsep yang ada. Misalnya, dalam Scala bahkan fungsi adalah objek, jadi saya kira fungsi Java akan dibungkus lagi menjadi beberapa jenis objek ketika mereka menjadi terlihat oleh Scala.
  3. Bahasa Scala atau Clojure akan terus mendukung interoperabilitas hingga Java 6 atau 7, tanpa mengikuti perkembangan Java terbaru. Ini membutuhkan versi Java yang lebih lama masih didukung (setidaknya oleh OpenJDK atau proyek lain), sehingga bahasa-bahasa ini dapat didasarkan pada cabang Jawa yang lebih konservatif / stabil.

Ringkasnya: dapatkah kita berharap bahwa perkembangan Jawa di masa depan akan berdampak pada bahasa-bahasa seperti Scala dan Clojure untuk mempertahankan interoperabilitas dengan Jawa? Apakah sudah ada (tautan ke) diskusi berkelanjutan tentang topik ini?

Catatan

Saya dapat membayangkan bahwa Scala, Clojure, dan bahasa berbasis JVM lainnya tidak akan memiliki masalah besar dalam memperbarui implementasi mereka ke versi JVM yang lebih baru (dan bahwa fitur JVM baru akan membuat implementasi ini lebih mudah). Pertanyaan saya berfokus pada fitur Java sebagai bahasa dan apakah / bagaimana bahasa JVM lain akan dapat "melihat" / menggunakan fitur-fitur baru ini, bukan pada apakah bahasa berbasis JVM akan berjalan pada JVM terbaru.

Giorgio
sumber
6
Tidak tepat untuk mengatakan bahwa Scala dll bergantung pada Java. Mereka bergantung pada kode byte JVM. Semua fitur interoperabilitas berurusan dengan bytecode, bukan kode sumber bahasa Jawa, jadi perubahan apa pun yang dilakukan pada Java itu sendiri bukanlah ancaman. Hanya perubahan yang dilakukan pada JVM yang dapat memengaruhi bahasa ini, dan JVM sangat konservatif - pada dasarnya tidak pernah menghilangkan dukungan untuk apa pun. Bahkan, sebagian besar perubahan dalam JVM saat ini dimaksudkan khusus untuk bahasa dinamis yang lebih baru.
Kilian Foth
@Kilian Foth: Sejauh yang saya tahu Scala Stringadalah Java String. Jadi Scala menggunakan kelas perpustakaan Java tertentu. Tetapi saya dapat mengubah formulasi jika Anda pikir itu terlalu kuat.
Giorgio
@Kilian Foth: Saya telah menghapus istilah tergantung karena fokus pertanyaan saya lebih pada interoperabilitas antara Scala dan Java resp. Clojure dan Jawa.
Giorgio
@KilianFoth Ini harus menjadi jawaban karena membahas masalah utama dari pertanyaan. Tujuan nomor satu dari setiap rilis Java baru adalah kompatibilitas mundur.
maple_shaft
3
@maple_shaft: Saya telah memperbaiki pertanyaan saya dan menghapus kata "depend". Seperti yang telah saya tunjukkan dalam komentar lain, masalah saya bukanlah bagaimana Scala atau Clojure bergantung pada fitur Java atau JVM, tetapi bagaimana Scala / Clojure dapat "melihat" fitur Java. Sejauh yang saya tahu mereka dapat melihat fitur Java 6 seperti kelas, antarmuka, objek, metode, tipe data primitif. Ini memungkinkan Scala / Clojure untuk menggunakan (memanggil) kode Java 6. Pertanyaan saya adalah, apakah bahasa-bahasa ini juga "melihat" (dan, karenanya, dapat menggunakan) konstruksi bahasa Jawa di masa depan atau apakah ini memerlukan ekstensi ke bahasa Scala / Clojure?
Giorgio

Jawaban:

15

Sebenarnya Java 8 tidak memperkenalkan banyak yang akan merugikan bahasa JVM lain yang berinteraksi dengan Java. Pekerjaan yang dilakukan pada Lambdas membantu memperbaiki sejumlah masalah kecil di sekitar invokedynamic, MethodHandles, MethodReferences dll - tetapi selain itu terus berjalan seperti biasa. Yang mengatakan, ada banyak sekali API yang bahasa JVM lainnya berpotensi memanggil sekarang. Yang mana yang akan mereka gunakan secara default atau tidak, terserah mereka.

Perubahan terbesar yang mempengaruhi interop sebenarnya datang dengan Java 7 - dengan bytecode invokedynamic yang memungkinkan panggilan dinamis / lambat dalam JVM - sesuatu yang awalnya dirancang untuk bahasa lain di JVM. Sejak itu telah sangat berguna diadaptasi untuk Lamdbas, sehingga pada Java 8, Java akan benar-benar mulai memancarkan bytecode ini.

Beberapa bahasa (JRuby misalnya) sudah banyak menggunakan invokedynamic, sementara yang lain (Scala, Groovy et al) masih menyelidiki penggunaannya atau masih dalam tahap awal menambalnya. Secara teori ini membuat panggilan dinamis mereka hampir sama berkinerja seperti yang sudah ada Panggilan Java invokestatic, yang bertentangan dengan segudang solusi yang lebih lambat yang terpaksa mereka gunakan di masa lalu.

Java 9 akan membawa lebih banyak tantangan untuk bahasa JVM dengan proyek Jigsaw datang ke platform yang akan menjadi awal dari akhir untuk pemuatan kelas tradisional dan classpath untuk JVM. Orang-orang bahasa JVM cukup sadar akan hal ini dan saya mengharapkan kolaborasi yang masuk akal terjadi.

Martijn Verburg
sumber
1
Tapi, sejauh yang saya tahu, penutupan Scala adalah objek.
Giorgio
1
Ya. Scala baru saja menjatuhkan dukungan untuk Java 1.5, itu akan lama sampai mereka turun 1,6.
Jörg W Mittag
1
@Iorgio Fitur bahasa Java tidak penting karena sebagian besar dari mereka menyamakan trik bytecode ketika dikompilasi. Jika kami menerima bahwa JVM akan selalu kompatibel ke belakang, bahkan jika bytecode baru diperkenalkan, maka Scala tidak akan terpengaruh dan dapat memilih untuk mengambil keuntungan dari fitur-fitur JVM baru itu dengan nyaman.
maple_shaft
1
"Fitur bahasa Java tidak penting karena sebagian besar dari mereka menyamakan trik bytecode ketika dikompilasi.": Jika bahasa lain ingin menggunakan konstruk Java, ia harus dapat mengenali bytecode yang dihasilkan untuk konstruk itu. Jika Java memperkenalkan konstruksi baru yang memetakan ke bytecode baru, bahasa host setidaknya harus mengimplementasikan pembungkus / antarmuka baru untuk mengenali dan menggunakan bytecode baru. Misalnya jika lambda Java 8 tidak membuat objek tetapi beberapa konstruk baru dengan bytecode baru untuk itu, bahasa host harus disesuaikan untuk mengenalinya.
Giorgio
2
@Iorgio: Tentu, tetapi tidak ada perubahan seperti yang direncanakan untuk platform Java 8. Bahkan, JVMs hanya diperpanjang dua kali dalam seluruh sejarah Java Platform, pada tahun 2003 dan 2010, dan kedua kalinya (pengenalan invokedynamicbytecode) adalah khusus untuk bahasa dukungan lainnya dari Jawa; sebenarnya, bahasa Java 7 tidak mendukung atau menggunakan bytecode itu.
Jörg W Mittag
2

Scala akan ditinggalkan ketika Jawa menambahkan lambdas karena Java lambdas mendapatkan jenis berdasarkan konteks yang digunakan, sedangkan Scala lambdas mendapatkan jenis berdasarkan aritas, jenis parameter dan jenis kembali, jadi misalnya,

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

dari Java 8 dapat ditulis dalam Scala sebagai:

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

kecuali jika Anda menggunakan / menulis beberapa pembungkus yang mengonversi Unit Scala () => ke Runnable.

Ricky Clarkson
sumber
Terima kasih atas jawabannya dan juga untuk menjawab pertanyaan saya (+1). Jika saya mengerti dengan benar, Scala harus terus menggunakan kelas anonim untuk membuat instance antarmuka dalam konteks di mana Java 8 akan menggunakan lambdas (karena Java 8 lambdas memiliki semantik yang berbeda dari Scala lambdas). Poin lain yang tidak jelas bagi saya adalah apa yang akan terjadi jika metode Java mengembalikan Java lambda. Apa yang terjadi jika kelas Scala memanggil metode itu? Apa yang akan menjadi tipe pengembalian di Scala?
Giorgio
1
@Giorgio Di Java 8 ekspresi lambda adalah pintasan tingkat bahasa untuk membuat instance antarmuka yang mendeklarasikan metode tunggal dan yang ditangguhkan oleh konteks. Jadi ketika metode Java 8 mengembalikan lambda, sebenarnya mengembalikan sebuah instance dari antarmuka yang dinyatakan sebagai tipe pengembalian metode. Pada Scala 2.9.1, tipe kembali akan menjadi hanya sebuah contoh dari beberapa antarmuka mengatakan (Runnable atau Pembanding) yang Anda tidak dapat memperlakukan sebagai Scala lambda, kecuali jika Anda atau rilis masa depan perpustakaan Scala memperkenalkan konversi implisit dari yang antarmuka ke jenis Scala lambda.
hellodanylo
@SkyDan: Ok, jadi Scala akan melihat Java lambdas sebagai objek yang mengimplementasikan beberapa antarmuka. Poin ini tidak jelas bagi saya: Saya pikir Java akan menghasilkan beberapa bytecode yang berbeda dari suatu objek. Tapi itu harus menjadi objek di bawah tenda, kalau tidak itu tidak akan diakui sebagai implementasi antarmuka. Saya pikir saya mengerti sekarang.
Giorgio
@Giorgio, juga jika Anda ingin tahu lebih banyak tentang perubahan terkait lambda di Java 8 dan kekuatan yang mendorong perubahan ini, saya sarankan Anda untuk membaca ikhtisar yang menarik dan terperinci dari proyek Lambda ini .
hellodanylo
@SkyDan: Membaca itu sekarang. Tampak bagi saya bahwa lambdas memang mewakili objek (meskipun jenis / antarmuka disimpulkan dari konteks di mana mereka didefinisikan). Jadi informasi yang diberikan di mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… ("lambdas bukan objek") tidak benar atau, setidaknya, menyesatkan.
Giorgio