4

私は (SML の本から) SML の関数は常にただ 1 つの引数を取ることを学びました: タプルです。複数の引数を取る関数は、関数バインディングでタプル バインディングを使用して実装された、引数として 1 つのタプルを取る単なる関数です。この点は理解しています。

しかし、この後、本は私が理解できないことを言っています:

this point makes SML language flexible and elegant design, and you can do something useful that you cannot do in Java.

この設計が言語を柔軟にするのはなぜですか? SMLはできるがJavaはできないというテキストは何を参照していますか?

4

2 に答える 2

6

複数の引数の代わりにタプルを使用すると、高階関数が任意の「アリティ」の関数で動作できるという意味で柔軟性が追加されます。たとえば、 list を作成するには、次のよう[f x, f y, f z]に高階関数を使用できます。map

map f [x, y, z]

それはとても簡単です - どの言語でもできます。fしかし、実際に 2 つの引数が必要な場合を考えてみましょう。が真の二項関数である場合f(SML にそのような関数があると仮定)、map単項関数ではなく二項関数で動作する別のバージョンの が必要になります (3 項関数を使用する場合は、それらのバージョンも必要です)。ただし、タプルを使用すると、次のように記述できます。

map f [(x,a), (y,b), (z,c)]

これにより、リストが作成されます[f (x,a), f (y,b), f (z,c)]

PS: 複数の引数を必要とするすべての関数が SML でタプルを取るというのは本当ではありません。多くの場合、関数はタプルではなくカリー化を使用して複数の引数を表しますが、あなたの本はまだカリー化されていないと思います。カリー化された関数は、上記と同じ方法では使用できないため、その意味では一般的ではありません。

于 2013-01-28T00:42:16.797 に答える
3

実際、あなたはこれをまったく理解していないと思います。

まず第一に、SML の関数はタプルを引数としてとらず、何でも引数として取ることができます。複数の引数を渡す手段としてタプルを使用すると便利な場合があります。たとえば、関数はレコード、整数、文字列を引数として取り、別の関数を引数として取ります。引数として単位を取ることができるという意味で、「引数なし」を取ることができるとも言えます。

「複数の引数」を取る関数についてのあなたの声明を正しく理解していれば、あなたはカリー化について話していることになります。例えば

fun add x y = x + y

SML では、カリー化は派生形式 (シンタックス シュガー) として実装されます。これが実際にどのように機能するかについて詳しくは、この回答を参照してください。要約すると、SML には無名関数しかありませんが、後で「参照」/使用できるように名前にバインドできます。

見よ、とりとめのないことが始まろうとしている。

何かの柔軟性について話す前に、私がそれについてどのように考えているかを述べるためだと思います. 私は、プログラミング言語の柔軟性に関するこの定義がとても気に入ってます。

SML の場合、小さくて単純なコア言語が選択されています。これにより、コンパイラとインタープリタの実装が容易になります。柔軟性は、SML 言語の多くの機能が、無名関数、パターン マッチング、SML に高階関数があるという事実など、これらのコア言語機能を使用して実装されているという形でもたらされます。
この例としては、カリー化、case 式、レコード セレクター、if-the-else 式、式シーケンスがあります。

これにより、SML コア言語が非常に柔軟になり、率直に言って非常にエレガントになったと言えます。

SML でできること、Java でできないこと (このコンテキストでは) に関して、著者がどこに行っていたのかはよくわかりません。ただし、Javaでも何でもできるので、作者が少し偏っている可能性があると確信しています。ただし、膨大な量のコーディングが必要になる場合があります:)

于 2013-01-28T01:05:05.560 に答える