2013-03-31 41 views
32

Trình biên dịch F # hiện tại được viết bằng F #, là mã nguồn mở và chạy trên .Net và Mono, cho phép nó thực thi trên nhiều nền tảng bao gồm Windows, Mac và Linux. F # 's Code Quotations cơ chế đã được sử dụng để biên dịch F # thành JavaScript trong các dự án như WebSharper, PitFunScript. Dường như có sự quan tâm đến việc chạy F# code on the JVM.Cách dễ nhất để xây dựng trình biên dịch F # chạy trên JVM và tạo ra bytecode Java là gì?

Tôi tin rằng một phiên bản của OCaml compiler đã được sử dụng ban đầu Bootstrap trình biên dịch F #.

Nếu ai đó muốn xây dựng một F # biên dịch chạy trên JVM nó sẽ dễ dàng hơn để:

  1. Sửa đổi F # biên dịch hiện có để phát ra Java bytecode và sau đó biên dịch F # biên dịch với nó?
  2. Sử dụng trình biên dịch ML dựa trên JVM như Yeti để Bootstrap trình biên dịch F # tối thiểu trên JVM?
  3. Viết lại trình biên dịch F # từ đầu trong Java khi dự án fjord dường như đang cố gắng?
  4. Cái gì khác?
+0

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 –

Trả lời

12

Một tùy chọn khác có lẽ nên được xem xét là chuyển đổi mã byte .NET CLR thành mã byte JVM như http://www.ikvm.net thực hiện với JVM> mã byte CLR. Mặc dù cách tiếp cận này là considered and dismissed by the fjord owner.

Bắt đầu mua từ trên cùng với tùy chọn 1) và có nhóm biên dịch F # có các phụ trợ có thể cắm được có thể phát ra âm thanh Java bytecode theo lý thuyết như nó sẽ tạo ra giải pháp được đánh bóng nhất.

Nhưng nếu bạn nhìn vào các ngôn ngữ khác đã được chuyển sang các nền tảng khác thì điều này hiếm khi xảy ra. Hầu hết thời gian nó được viết lại từ đầu. Nhưng điều này cũng có thể do nhóm ngôn ngữ gốc không quan tâm đến việc hỗ trợ nền tảng thay thế và việc triển khai máy chủ ban đầu có thể không hỗ trợ nhiều chương trình phụ trợ và đã quá chậm để có thể bắt đầu bằng .

Linh cảm của tôi là sự kết hợp viết lại từ đầu và có thể thực hiện nhiều việc chia sẻ và tự động hóa mã nhất có thể từ việc triển khai ban đầu. Ví dụ. nếu các bộ thử nghiệm có thể được tái sử dụng cho cả hai triển khai, nó sẽ mất rất nhiều gánh nặng ngoài cổng JVM và đi một chặng đường dài trong việc đảm bảo tính chẵn lẻ ngôn ngữ.

+0

Cảm ơn! Tôi đồng ý, một phụ trợ F # có thể cắm được sẽ cung cấp giải pháp được đánh bóng nhất. Nó xuất hiện [Scala.Net] (http://www.scala-lang.org/node/10299) đã sử dụng IKVM như một "yếu tố quan trọng để khởi động" khi đi theo cách khác từ Java sang .Net. [Clojure-CLR] (https://github.com/richhickey/clojure-clr) dường như đã sử dụng C# và Clojure. Tôi hy vọng rằng một phụ trợ có thể cắm được cho F # có thể trong thời gian không hợp tác giữa nhóm F # và cộng đồng nguồn mở, và điều đó sẽ dẫn đến hỗ trợ JVM hạng nhất, mặc dù Nhà cung cấp Loại tới Java có thể đủ hỗ trợ cho nhiều nhiệm vụ. –

+0

Không IKVM chỉ hoạt động ngược lại? – t0yv0

+1

@toyvo đúng, mặc dù cách tiếp cận ở cấp mã byte vẫn là một tùy chọn, tôi đã cập nhật câu trả lời để bao gồm các câu hỏi thường gặp của penberg về phương pháp này. – mythz

8

Tôi nghi ngờ mọi cách tiếp cận sẽ là rất nhiều công việc, nhưng tôi nghĩ đề xuất đầu tiên của bạn là gợi ý duy nhất tránh giới thiệu nhiều lỗi không tương thích và lỗi bổ sung. Trình biên dịch khá phức tạp và có rất nhiều trường hợp góc xung quanh độ phân giải quá tải, vv (và spec có thể có khoảng trống quá), do đó, có vẻ như rất khó có thể triển khai mới sẽ có ngữ nghĩa tương thích nhất quán.

+0

Cảm ơn! Trình biên dịch F # có vẻ khá phức tạp (và mạnh mẽ) với tôi nữa, vì vậy cho khả năng tương thích, tôi đồng ý sửa đổi nguồn của trình biên dịch hiện tại, hãy cảm thấy một lựa chọn tốt. –

9

Có một dự án biên dịch OCaml cho JVM, OCaml-Java: nó khá hoàn chỉnh và đặc biệt có thể biên dịch trình biên dịch OCAMl (viết bằng OCaml). Tôi không chắc chắn về khía cạnh nào của ngôn ngữ F # mà bạn quan tâm, nhưng nếu bạn chủ yếu xem xét việc có được một ngôn ngữ chức năng được đánh máy chặt chẽ với JVM, đó có thể là một lựa chọn tốt.

+0

Cảm ơn! OCaml-Java có vẻ thú vị và OCaml khá giống với F #. Nó có thể hữu ích cho một số dự án. Tôi đoán nó cũng có thể là một con đường khác để bootstrap F #. [F # thay đổi thành OCaml] (http://stackoverflow.com/questions/179492/f-changes-to-ocaml) sẽ thú vị nếu có [cú pháp ánh sáng] (http://msdn.microsoft.com/en -us/library/dd233199.aspx), [mẫu hoạt động] (http://msdn.microsoft.com/en-us/library/dd233248.aspx) và [nhà cung cấp loại] (http://blogs.msdn.com /b/dsyme/archive/2013/01/30/twelve-type-providers-in-pictures.aspx). –

11

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 đó:

  1. Rất nhiều mã trong BCL là đục (bản địa) - và bạn không thể dịch ngược nó

  2. 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.

  3. 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.

  4. 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.

1

Sửa trình biên dịch F # hiện có để phát ra Java bytecode và sau đó biên dịch trình biên dịch F # với nó? Sử dụng trình biên dịch ML dựa trên JVM như Yeti để Bootstrap trình biên dịch F # tối thiểu trên JVM?

Việc chuyển trình biên dịch không quá khó nếu được viết bằng F #.

Tôi có thể đi theo cách đầu tiên, vì đây là cách duy nhất có thể hy vọng giữ trình biên dịch mới đồng bộ với trình biên dịch Fnet .net.

Viết lại trình biên dịch F # từ đầu trong Java khi dự án vịnh hẹp dường như đang cố gắng?

Đây chắc chắn là cách tiếp cận ít thanh lịch nhất, IMHO.

Cái gì khác?

Khi trình biên dịch hoàn tất, bạn sẽ có 90% công việc còn lại để thực hiện.

Ví dụ, không biết nhiều F #, nhưng tôi cho rằng rất dễ sử dụng bất kỳ thư viện .NET nào. Điều đó có nghĩa, vấn đề cơ bản là chuyển đổi hệ sinh thái .NET, bằng cách nào đó.

+0

Có chà xát. Việc chuyển các nguồn F # hiện tại sẽ yêu cầu làm cho các thư viện lớp .NET có sẵn trên nền tảng đích (JVM). Có cổng .NET BCL đến JVM là một thứ tự khá cao, đặc biệt là một điều kiện tiên quyết. – Justin

0

Tôi đang tìm kiếm thứ gì đó trong các dòng tương tự, mặc dù nó giống như một trình biên dịch/biên dịch F # tới Akka. Theo như F # -> JVM có liên quan, tôi đã xem xét hai tùy chọn không sẵn sàng sản xuất:

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

    2. F# -> [Funscript][2] -> [Vert.X][3] -> JVM 
Các vấn đề liên quan