2013-03-31 4 views
32

現在のF#コンパイラはF#で書かれています。オープンソースで、.NetとMonoで動作し、Windows、Mac、Linuxなどの多くのプラットフォームで実行できます。 F#のCode Quotationsメカニズムは、WebSharper,PitFunScriptなどのプロジェクトでF#をJavaScriptにコンパイルするために使用されています。また、F# code on the JVMを実行することに興味があるようです。JVM上で動作し、Javaバイトコードを生成するF#コンパイラを構築する最も簡単な方法は何ですか?

OCaml compilerのバージョンは、もともとF#コンパイラBootstrapに使用されていたと思います。

誰かがJVM上で動作するF#コンパイラを構築したい場合、それはに容易になるだろう:

  1. Java bytecodeを放出し、それをF#コンパイラをコンパイルするために、既存のF#コンパイラを修正しますか?
  2. YetiのようなJVMベースのMLコンパイラを使用して、最小限のF#コンパイラをJVMにブートストラップしますか?
  3. fjordプロジェクトが試行されているように、JavaでF#コンパイラを最初から書き直しますか?
  4. 他に何かありますか?
+0

は、[ハッカーニュース]にフィヨルドにいくつかの最近の議論に注目する価値があるかもしれません(https://news.ycombinator.com: - 限りF#のように> JVMが懸念している、私は2つの非常にない生産準備オプションに出くわしました/ item?id = 5464925)、[Reddit](http://www.reddit.com/r/fsharp/comments/1b8nqg/fjord_implementation_of_f_for_the_jvm/)、プロジェクトの[Issues](https://github.com/penberg/fjord/issues/1)page –

答えて

12

おそらく考慮すべきもう1つのオプションは、.NET CLRバイトコードをhttp://www.ikvm.netのようなJVMバイトコードに変換することです(JVM> CLRバイトコードを使用)。このアプローチはconsidered and dismissed by the fjord ownerでした。

オプション1)でトップからバイイングを取得し、F#コンパイラチームには、最も洗練されたソリューションを生成するようなJavaバイトコードサウンドを放出するプラグイン可能なバックエンドがあります。

しかし、異なるプラットフォームに移植されている他の言語を見ると、これはまれです。ほとんどの場合、最初から書き直されています。しかしこれはまた、オリジナルの言語チームが代替プラットフォームをサポートすることに興味がなく、元のホスト実装が複数のバックエンドをサポートできなかった可能性があります。 。

私の勘違いは、元の実装からできるだけ多くのコード共有と自動化を行うことができるようになりました。例えば。両方の実装でテストスイートを再利用できる場合は、JVMポートから多くの負担がかかり、言語パリティを確保するために長い道のりをとります。

+0

ありがとう!私は同意します。プラグイン可能なF#バックエンドは、最も洗練されたソリューションを提供します。それは、Javaから.Netへの別の方法に行くとき、[Scala.Net](http://www.scala-lang.org/node/10299)がIKVMを「ブートストラップの重要なイネーブラ」として使用したように見えます。 [Clojure-CLR](https://github.com/richhickey/clojure-clr)はC#とClojureを使用したようです。 F#チームのためのプラグイン可能なバックエンドがF#チームとオープンソースコミュニティとの協調から時折出てくる可能性がありますが、これはファーストクラスのJVMサポートにつながりますが、Type Provider to Javaは十分なサポート多くのタスクのために。 –

+0

IKVMは逆にしか動作しませんか? – t0yv0

+1

@toyvoのように、バイトコードレベルのアプローチはまだ選択肢ですが、私はこのアプローチに関するpenbergのFAQを含めるように答えを更新しました。 – mythz

8

多くの作業が必要と思われますが、多くの追加の非互換性とバグの導入を避ける唯一の方法だと思います。コンパイラは非常に複雑で、オーバーロード解決などのコーナーケースがたくさんあります(スペックにもギャップがあるかもしれません)ので、新しい実装では一貫して互換性のあるセマンティクスがあるとは思われません。

+0

ありがとう! F#コンパイラは私にとってはかなり複雑で(強力な)ように見えます。互換性のために、私は既存のコンパイラのソースを変更することが良い選択肢に見えると感じます。 –

9

OCamlをJVMのOCaml-Javaにコンパイルするプロジェクトがあります。これはかなり完成しており、特にOCamlのコンパイラ(OCamlで書かれたもの)をコンパイルできます。興味のあるF#言語の側面はわかりませんが、JVMに成熟した厳密な型指定された関数型言語を主に見ているのであれば、良い選択肢かもしれません。

+0

ありがとう! OCaml-Javaは面白く見え、O​​CamlはF#と非常に似ています。これは、いくつかのプロジェクトでは役に立ちます。私はそれがF#をブートストラップする別のルートかもしれないと思います。 [F#がOCamlに変わる](http://stackoverflow.com/questions/179492/f-changes-to-ocaml)には[light syntax](http://msdn.microsoft.com/ja -us/library/dd233199.aspx)、[アクティブパターン](http://msdn.microsoft.com/en-us/library/dd233248.aspx)、[型プロバイダ](http://blogs.msdn.com /b/dsyme/archive/2013/01/30/twelve-type-providers-in-pictures.aspx)。 –

11

もし私が本当にこれをやらなければならなかったら、おそらく#1のアプローチから始めるでしょう - JVMバックエンドを既存のコンパイラに追加してください。しかし、私はまた、別のターゲットVMを主張しようとします。

WebSharperの著者として、引用するとF#のような優れたプログラムを書くことができますが、制限があり、最適化されていないことを保証できます。潜在的なJVM F#ユーザーのために、バーはもっと高いでしょう - 完全な言語互換性とそれに匹敵するパフォーマンスだと思います。これは非常に難しいです。

たとえば、テールコールを実行します。 WebSharperでは、ヒューリスティックを適用して、JavaScriptのループへのローカルテールコールを最適化しますが、それだけでは不十分です。一般的なF#ライブラリのように、一般的にTCOに頼ることはできません。これはWebSharperにとっては問題ありません。ユーザーは完全なF#を期待していませんが、JVMのF#ポートではOKではありません。私はほとんどのJVMの実装はTCOを行わないと考えているので、間接的に実装しなければならず、パフォーマンスが低下します。

@mythzで言及されているバイトコードの再コンパイルのアプローチは、F#を移植する以外にも理想的です。理想的には、JVMに.NETソフトウェアを移植することができます。内部のWebSharper 3.0プロジェクトで.NETバイトコード解析を行ったところ、JavaScriptのF#引用ではなく.NETバイトコードをコンパイルするオプションが検討されています。

  1. BCLのコードの多くは不透明(ネイティブ)である - そしてあなたはそれが

  2. ジェネリックモデルはかなり複雑でコンパイルすることはできません。しかし、そこに巨大な課題があります。私は、クラスとメソッドのジェネリック、インスタンス化、型生成、および基本的なリフレクションを、精度と妥当なパフォーマンスでモデリングするJavaScriptランタイムを実装しました。これは、クロージャを使用した動的JavaScriptでは難しく、JVMでパフォーマンスを上げるのはかなり難しいようですが、単純な解決策は見当たりません。

  3. 値の種類によって、バイトコードに重大な複雑さが生じます。私はWebSharper 3.0のためにこれをまだ理解していません。それらは、あなたが移植したい多くのライブラリによって広く使われているので、無視することもできません。

  4. 同様に、基本リフレクションは多くの現実の.NETライブラリで使用されています。また、ネイティブコードとジェネリックスと値型の適切なサポートの両方でクロスコンパイルするのは難しいことです。

また、バイトコードアプローチでは、テールコールの実装方法に関する質問は削除されません。 AFAIK、Scalaはテールコールを実装していません。彼らは確かに才能とそれを行うための資金を持っています - 彼らはそうではないという事実は、JVM上でTCOを実践することがどれほど実用的かを私に教えてくれます。私たちの.NET - > JavaScriptポートでは、私はおそらく同様のルートに行くでしょう - あなたが特に動作するトランポリングを求めない限り、TCOの保証はありませんが、パフォーマンスには1桁または2桁のコストがかかります。

1

既存のF#コンパイラを修正してJavaバイトコードを生成し、それを使ってF#コンパイラをコンパイルしますか? YetiのようなJVMベースのMLコンパイラを使用して、JVM上に最小限のF#コンパイラをブートストラップしますか?

F#で記述されている場合、コンパイラの移植はそれほど難しくありません。

これは、新しいコンパイラを.net F#コンパイラと同期させておくことができる唯一の方法であるため、おそらく最初の方法になります。

フィヨルドプロジェクトが試行しているように、JavaでF#コンパイラを最初から書き直してください。

これは確かに、最も洗練されたアプローチではありません。

他に何か?

コンパイラが完了すると、90%の作業が残ります。

たとえば、多くのF#を知らないのですが、そこに.NETライブラリを使用するのは簡単だと思います。 つまり、基本的な問題は、何とか.NETエコシステムを移植することです。

+0

擦れがあります。現在のF#ソースを移植するには、ターゲットプラットフォーム(JVM)で.NETクラスライブラリを使用できるようにする必要があります。 .NET BCLをJVMに移植することは、特に必要条件として非常に難しいことです。 – Justin

0

私は類似の行を探していましたが、Akkaの翻訳者/コンパイラの方がF#の方が似ていました。

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

    2. F# -> [Funscript][2] -> [Vert.X][3] -> JVM 
関連する問題