2012-05-19 5 views
6

"Introduction to Caml" Camlの中で、複数の引数関数ではなく、タプルのためにカレー関数定義を使用することをお勧めし、なぜOCamlで引数をタプルするのが好きですか?

注意を言います。

'a * 'b -> 'c'a -> 'b -> 'c呼び出し規約を比較します。

SML/NJで作業するとき、入力と出力の両方にタプルタイプを使用することになりました。('a * 'b) -> ('c * 'd)タプルを使用して複数の入力を表現すると、複数の出力を表現する方法が対称に見えます。

タプル引数よりもOCaml関数の宣言でカリングが推奨されるのはなぜですか?カリー化/部分的な評価を可能にするだけで柔軟性が増しますか、OCamlコンパイラの実装の詳細から得られる他の利点がありますか?

+2

Caml-light以降のほとんどの関数のカリング選択については、「ZINC実験:ML言語の経済的な実装」のレポートで説明しています。私が覚えていることの1つは、適切な評価スキーム(レポートに記載されている)を使用すると、カリーされた関数は呼び出されるために割り当てを必要としないということです。 http://caml.inria.fr/pub/papers/xleroy-zinc.ps.gz –

+0

@PascalCuoq、タプルを割り当て、展開してGCedする必要はありますか? –

+0

はい、既存のタプル( 'ft')で関数を呼び出すことも意図している場合、短命の一時タプル'(x、y) 'を割り当てて'何を持っているかを知るためには 'x'と' y'だけです。 –

答えて

2

はい、主に表記上の利便性と部分的な適用を行う柔軟性です。カールされた関数はOCamlでは慣用的であり、コンパイラはタプル関数よりもいくらか優れていると思われます(SMLコンパイラは一般的にタプルを最適化します)。

タプルの賛成論は、あなたが言及する引数/結果の対称性(関数を構成するときに特に便利です)と、おそらく表記上の親しみ(少なくとも非機能性の世界から来た人々にとっては)です。

1

OCamlの最適化に関するコメント。

OCamlでは、タプルは引数として渡すときに常に割り当てられることに気付きました。たとえプライマリヒープでの割り当てがocamlで速い場合でも、何もしないよりも長いのです。したがって、引数としてタプルを渡すたびに、タプルの割り当てと塗りつぶしに時間がかかります。

私は、ocamlコンパイラがタプルを構築する必要がない場合を最適化すると予想しました。たとえば、呼び出された関数をインライン化するときは、タプルコンポーネントだけを使用でき、タプル自体は使用できません。したがって、タプルは無視することができます。残念なことに、この場合、OCamlは無駄なタプルを取り除いても割り当てを実行しません。このため、コードの重要な部分にタプルを使用することはお勧めできません。

+0

これはもはや真実ではないと思います。 [「OCamlは私が思っていたよりスマートです」](https://blogs.janestreet.com/ocaml-is-smarter-than-i-thought/)は、「私はインライン展開を妨げましたが、割り当てはまだありませんでした!なぜ?OCamlは、タプルを取る関数を最適化して、レジスタを通って渡されたタプルの要素を取得することができますが、コンパイラは割り当てを必要としないことを認識しました。 –

5

OCamlの標準ライブラリ関数はカリー化されていますが、標準MLでは一般的にいくつかの高次関数を除いてはありません。しかしながら、言語に焼き付けられた1つの違いがある。演算子(例えば(*))がOCamlでカレーされている(例えばint -> int -> int)。一方、それらは標準MLにおいて甘くない(例えばop*(int * int) -> intとすることができる)。そのため、ビルトインの高次関数(foldなど)もOCamlでカレート化され、標準MLで荒らされている関数を取ります。それはあなたの機能がそれで動作することを意味し、それぞれの規約に従う必要があります。

+1

良い点。選択肢がベークされた別のインスタンスがあります:データ型コンストラクタ。 SMLではタプルされ、ハスケルではカレーされます。不思議にも、OCamlではタプルされています。これは残りの言語との不一致です。 –

+1

タプルされるデータ型コンストラクタの背後にあるより深い意味は、タプルが匿名の特殊なケースのデータコンストラクタであるということです。 –

関連する問題