Nếu tôi thực sự phải làm điều này, tôi có thể bắt đầu với phương pháp # 1 - thêm phần phụ trợ JVM vào trình biên dịch hiện có. Nhưng tôi cũng sẽ cố gắng tranh luận cho một máy ảo mục tiêu khác.
Báo giá không phù hợp lắm - với tư cách là tác giả của WebSharper tôi có thể đảm bảo với bạn rằng khi trích dẫn có thể cung cấp cho bạn ngôn ngữ F # giống như chương trình, chúng hạn chế và không được tối ưu hóa. Tôi tưởng tượng rằng đối với người dùng JVM tiềm năng F # thanh sẽ cao hơn rất nhiều - khả năng tương thích ngôn ngữ đầy đủ và hiệu suất tương đương. Điều này rất khó. Ví dụ:
Lấy các cuộc gọi đuôi. Trong WebSharper, chúng tôi áp dụng các chẩn đoán để tối ưu hóa một số cuộc gọi đuôi cục bộ tới các vòng trong JavaScript, nhưng điều đó là không đủ - bạn không thể nói chung dựa vào TCO, như bạn làm trong các thư viện F # chung. Điều này là tốt cho WebSharper khi người dùng của chúng tôi không mong đợi có đầy đủ F #, nhưng sẽ không được chấp nhận cho một cổng JVM F #. Tôi tin rằng hầu hết các triển khai JVM không làm TCO, do đó, nó sẽ phải được thực hiện với một số indirection, giới thiệu một hit hiệu suất.
Cách tiếp cận biên dịch lại bytecode được đề cập bởi @mythz nghe rất hấp dẫn vì nó cho phép nhiều hơn là chỉ chuyển F # - lý tưởng là nó cho phép chuyển phần mềm .NET sang JVM. Tôi đã làm việc khá một chút với phân tích .NET bytecode trên một dự án WebSharper 3.0 nội bộ - chúng ta đang xem xét tùy chọn biên dịch .NET bytecode thay vì F # trích dẫn thành JavaScript. Nhưng cũng có những thách thức rất lớn đó:
Rất nhiều mã trong BCL là đục (bản địa) - và bạn không thể dịch ngược nó
Mô hình Generics là khá phức tạp. Tôi đã thực hiện một thời gian chạy JavaScript mô hình lớp và phương pháp generics, instantiation, loại thế hệ, và phản ánh cơ bản với một số hiệu suất chính xác và hợp lý. Điều này đã đủ khó khăn trong JavaScript động với các bao đóng và có vẻ khá khó khăn để thực hiện theo cách thực hiện trên JVM - nhưng có lẽ tôi chỉ không thấy một giải pháp đơn giản.
Các loại giá trị tạo ra các biến chứng đáng kể trong bytecode. Tôi chưa tìm ra điều này cho WebSharper 3.0. Chúng cũng không thể bỏ qua, vì chúng được sử dụng rộng rãi bởi nhiều thư viện bạn muốn chuyển.
Tương tự như vậy, sự phản chiếu cơ bản được sử dụng trong nhiều thư viện thực tế .NET - và nó là một cơn ác mộng để biên dịch chéo cả về nhiều mã gốc và hỗ trợ thích hợp cho generics và các loại giá trị.
Ngoài ra, cách tiếp cận bytecode không loại bỏ câu hỏi về cách triển khai cuộc gọi đuôi. AFAIK, Scala không triển khai tailcalls. Họ chắc chắn là tài năng và kinh phí để làm điều đó - thực tế là họ không, nói với tôi rất nhiều về cách thực tế để làm TCO trên JVM. Đối với cổng .NET-> JavaScript của chúng tôi, có lẽ tôi sẽ đi một tuyến tương tự - không bảo đảm TCO trừ khi bạn yêu cầu trampolining sẽ hoạt động nhưng bạn phải trả một đơn đặt hàng (hoặc hai) hiệu suất.
có thể đáng chú ý một số cuộc thảo luận gần đây về Fjord trên [Hacker News] (https://news.ycombinator.com)/item? id = 5464925), [Reddit] (http://www.reddit.com/r/fsharp/comments/1b8nqg/fjord_implementation_of_f_for_the_jvm/) và [Vấn đề] của riêng dự án (https://github.com/penberg)/fjord/issues/1) page –