Pertanyaan Apa cara termudah untuk membangun kompiler # F yang berjalan di JVM dan menghasilkan bytecode Java?


F # Compiler saat ini ditulis dalam F #, adalah open source dan berjalan di .Net dan Mono, memungkinkannya untuk mengeksekusi pada banyak platform termasuk Windows, Mac dan Linux. F # 's Kutipan Kode mekanisme telah digunakan untuk mengkompilasi F # ke JavaScript dalam proyek-proyek seperti WebSharper, Lubang dan FunScript. Ada juga tampaknya ada minat dalam berlari F # kode di JVM.

Saya percaya versi dari OCaml compiler digunakan untuk awalnya Bootstrap kompiler F #.

Jika seseorang ingin membangun kompiler F # yang berjalan di JVM akan lebih mudah untuk:

  1. Ubah F # compiler yang ada untuk memancarkan Bytecode Java dan kemudian kompilasi kompilator F # dengan itu?
  2. Gunakan compiler ML berbasis JVM seperti Yeti untuk Bootstrap kompiler F # minimal pada JVM?
  3. Tulis ulang kompiler F # dari awal di Java sebagai fjord proyek tampaknya berusaha?
  4. Sesuatu yang lain?

32
2018-03-31 16:34


asal


Jawaban:


Pilihan lain yang mungkin harus dipertimbangkan adalah mengonversi kode byte .NET CLR ke dalam kode byte JVM http://www.ikvm.net hubungannya dengan kode byte JVM> CLR. Meskipun pendekatan ini telah dilakukan dianggap dan diberhentikan oleh pemilik fjord.

Mendapatkan buy-in dari atas dengan opsi 1) dan memiliki tim kompilator F # memiliki backend pluggable yang dapat memancarkan suara bytecode Java dalam teori seperti itu akan menghasilkan solusi yang paling halus.

Tetapi jika Anda melihat bahasa lain yang telah diporting ke berbagai platform, ini jarang terjadi. Sebagian besar waktu sudah ditulis ulang dari awal. Tetapi ini juga mungkin disebabkan oleh tim bahasa asli yang tidak tertarik untuk mendukung platform alternatif itu sendiri dan bahwa implementasi host asli mungkin belum mampu mendukung beberapa backend dan itu sudah terlalu lambat untuk ini menjadi opsi yang layak untuk memulai dengan .

Firasat saya adalah kombinasi penulisan ulang dari awal dan mampu melakukan sebanyak mungkin pembagian kode dan otomatisasi dari implementasi awal. Misalnya. jika rangkaian uji dapat digunakan kembali untuk kedua implementasi, akan banyak beban dari port JVM dan berjalan jauh dalam memastikan paritas bahasa.


12
2018-03-31 17:09



Jika saya benar-benar harus melakukan ini, saya mungkin akan mulai dengan pendekatan # 1 - tambahkan backend JVM ke kompiler yang ada. Tapi saya juga akan mencoba berdebat untuk target VM yang berbeda.

Kutipan tidak terlalu relevan - sebagai penulis WebSharper, saya dapat meyakinkan Anda bahwa sementara kutipan dapat memberi Anda bahasa seperti F # yang bagus untuk diprogram dengan, mereka bersifat membatasi, dan tidak dioptimalkan. Saya membayangkan bahwa untuk pengguna JVM F # potensial bar akan jauh lebih tinggi - kompatibilitas bahasa penuh dan kinerja yang sebanding. Ini sangat sulit.

Ambil panggilan ekor, misalnya. Di WebSharper kami menerapkan heuristik untuk mengoptimalkan beberapa panggilan ekor lokal ke loop dalam JavaScript, tetapi itu tidak cukup - Anda tidak dapat secara umum bergantung pada TCO, seperti yang Anda lakukan di F # perpustakaan umum. Ini baik untuk WebSharper karena pengguna kami tidak berharap memiliki F # penuh, tetapi tidak akan baik-baik saja untuk port JVM F #. Saya percaya sebagian besar implementasi JVM tidak melakukan TCO, jadi itu harus dilaksanakan dengan beberapa tipuan, memperkenalkan kinerja yang bagus.

Pendekatan kompilasi ulang bytecode yang disebutkan oleh @mythz terdengar sangat menarik karena memungkinkan lebih dari sekadar mem-porting F # - idealnya memungkinkan porting lebih banyak. Perangkat lunak NET ke JVM. Saya bekerja cukup sedikit dengan analisis bytecode .NET pada proyek WebSharper 3.0 internal - kami melihat opsi kompilasi .NET bytecode, bukan F # kutipan untuk JavaScript. Tetapi ada tantangan besar di sana:

  1. Banyak kode dalam BCL bersifat opak (asli) - dan Anda tidak dapat mendekompilasi

  2. Model generik cukup rumit. Saya telah menerapkan runtime JavaScript yang memodelkan kelas dan generik metode, instantiasi, generasi jenis, dan refleksi dasar dengan beberapa ketepatan dan kinerja yang wajar. Ini cukup sulit dalam JavaScript dinamis dengan penutupan dan tampaknya cukup sulit untuk dilakukan dengan cara yang bagus di JVM - tapi mungkin saya tidak melihat solusi sederhana.

  3. Tipe nilai menciptakan komplikasi yang signifikan dalam bytecode. Saya belum mengetahui yang ini untuk WebSharper 3.0. Mereka tidak dapat diabaikan, karena mereka digunakan secara luas oleh banyak perpustakaan yang ingin Anda porting.

  4. Demikian pula, refleksi dasar digunakan di banyak dunia. NET perpustakaan - dan itu adalah mimpi buruk untuk cross-compile baik dari segi banyak kode asli dan dukungan yang tepat untuk generik dan jenis nilai.

Juga, pendekatan bytecode tidak menghapus pertanyaan tentang bagaimana menerapkan panggilan ekor. AFAIK, Scala tidak mengimplementasikan tailcalls. Mereka pasti memiliki bakat dan dana untuk melakukan itu - fakta bahwa mereka tidak, memberi tahu saya banyak tentang bagaimana praktisnya melakukan TCO di JVM. Untuk kami. NET-> JavaScript port Saya mungkin akan pergi rute yang sama - tidak ada jaminan TCO kecuali Anda secara khusus meminta trampolining yang akan bekerja tetapi biaya Anda urutan besarnya (atau dua) dalam kinerja.


11
2018-04-01 21:53



Ada sebuah proyek yang mengkompilasi OCaml ke JVM, OCaml-Java: itu cukup lengkap dan khususnya dapat mengkompilasi sumber compiler (ditulis dalam OCaml) OCaml. Saya tidak yakin aspek mana dari F # bahasa yang Anda minati, tetapi jika Anda terutama ingin mendapatkan bahasa fungsional yang diketik ketat yang matang ke JVM, itu mungkin merupakan pilihan yang baik.


9
2018-03-31 17:22



Saya kira pendekatan apa pun akan banyak bekerja, tapi saya pikir saran pertama Anda adalah satu-satunya yang akan menghindari memasukkan banyak ketidakcocokan dan bug tambahan. Kompilator ini cukup kompleks dan ada banyak kasus sudut di sekitar resolusi overload, dll (dan spek mungkin memiliki celah juga), jadi tampaknya sangat tidak mungkin bahwa implementasi baru akan memiliki semantik yang kompatibel secara konsisten.


8
2018-03-31 16:52



Memodifikasi kompiler F # yang ada untuk memancarkan Java bytecode dan kemudian mengkompilasi kompilator F # dengan itu?   Gunakan ML compiler berbasis JVM seperti Yeti ke Bootstrap kompiler F # minimal pada JVM?

Porting compiler seharusnya tidak terlalu sulit jika ditulis dalam F #.

Saya mungkin akan pergi dengan cara pertama, karena ini adalah satu-satunya cara orang bisa berharap untuk menjaga kompilator baru sinkron dengan .net F # compiler.

Tulis ulang kompiler F # dari awal di Java karena proyek fjord nampaknya mencoba?

Ini tentu saja pendekatan yang paling tidak elegan, IMHO.

Sesuatu yang lain?

Ketika kompilator selesai, Anda akan memiliki 90% dari pekerjaan yang tersisa untuk dilakukan.

Sebagai contoh, tidak mengetahui banyak F #, tapi saya menganggap mudah untuk menggunakan perpustakaan .NET di luar sana. Itu berarti, masalah dasar adalah untuk port. NET ekosistem, entah bagaimana.


1
2018-04-02 14:11



Saya mencari sesuatu dengan garis yang sama, meskipun itu lebih seperti F # ke Akka translator / compiler. Sejauh F # -> JVM yang bersangkutan, saya menemukan dua opsi yang tidak cukup siap produksi:

  1. F# -> [Fjord][1] -> JVM.

  2. F# -> [Funscript][2] -> [Vert.X][3] -> JVM

0
2017-12-01 14:23