2011-07-25 15 views
2

F#の議論の順序がどうなるように見えるのはなぜですか? C#(同じコンパイルモデルを使用する)では問題ありません。私はこのしようとすると:F#コマンドラインファイルの順序?

# main.fs 
module Main 
let main = Printer.print_repeatedly 5 "hello, world" 

# printer.fs 
module Printer 
let print_repeatedly n str = for x in 1..n do printfn "%s" str 

を私はprinter.fsの前main.fsで(MicrosoftのとMonoの両方)コンパイラを実行し、私はエラーを取得する:

main.fs(4,12): error FS0039: The namespace or module 'Printer' is not defined 

私はprinter.fsを行う場合main.fsの前にコマンドラインで、それはいいです。コンパイラがF#にこれを必要とする理由はありますか?

答えて

7

F#では、コンパイラに渡されるファイルの順序は絶対に重要です.F#コンパイラは、プログラムを厳密に左から右に、上から下に読み込みます。 andを介して相互に再帰的な関係を明示的に指定しない限り、変数と型はそれらの前に定義されたもののみを参照することができます。

もしあなたがC#から来たのであれば、これは最初は制限のように思えるかもしれません。しかし実際には、実際にはコード編成の非常に効果的な実施であり、再帰的参照狂気を防ぐことが分かります。

前方参照は、実際にはプログラミング言語とコンパイラのかなり現代的な機能です(あなたはそれらを「無料」として入手できません)。初期のC++コンパイラで作業しなければならない場合は、これを可能にするための前方宣言(コンパイラに常に豊富ではない作業コストのメモリを持たせる)

+2

大きなプロジェクトのクリプトナイトである依存性管理が大幅に容易になることは言うまでもありません。 – Daniel

+0

私はC++を多く使っています。私はちょうどF#がC#型スタイルのコンパイルモデルにほとんど従うように見えることを奇妙に感じました。 –

+1

@Jonathan - 私は、F#とC#が共通のコンパイルモデルを共有する程度はどちらもCLIによって縛られていると思います。 C#は暗黙のインターフェイスの実装をサポートしています。これは推奨される「デフォルト」です.F#は明示的なインターフェイスの実装のみをサポートしています。 F#は、C#が実行している間はpublic static readonlyフィールドをサポートしていません。 F#では、C#が動作している間はオーバーライドされたメンバのシーリングをサポートしていません。 –