Next: , Previous: Introduction to Function Definition, Up: Function Definition   [Contents][Index]

36.2 Function

Function definition ·Programming ·

36.2.1 Ordinary functions

Maximaの中で関数を定義するためには、 :=演算子を使います。 例えば、

f(x) := sin(x)

は関数 fを定義します。 匿名関数も lambdaを使って生成することができます。 例えば、

f(i,j) := block ([], ...);
map (lambda ([i], i+1), l)

は、項それぞれに1を足したリストを返しますが、

lambda ([i, j], ...)

fの代わりに使うことができます。

(訳注: 元マニュアルの編集ミスでしょうか。以下の内容が一貫すると思います。

f(i) := i+1;
map (f, l)

は、項それぞれに1を足したリストを返しますが、

lambda ([i], i+1)

fの代わりに使うことができます。)

余分な引数のリストに割り当てられる最後の引数を持つことで、 引数が可変の関数も定義できます:

(訳注: 最後の引数変数を[]でくくると、残りの引数のリストがその引数変数に割り当てられます。)

(%i1) f ([u]) := u;
(%o1)                      f([u]) := u
(%i2) f (1, 2, 3, 4);
(%o2)                     [1, 2, 3, 4]
(%i3) f (a, b, [u]) := [a, b, u];
(%o3)               f(a, b, [u]) := [a, b, u]
(%i4) f (1, 2, 3, 4, 5, 6);
(%o4)                 [1, 2, [3, 4, 5, 6]]

関数の右辺は式です。 従って、もし一連の式が欲しいなら、

f(x) := (expr1, expr2, ...., exprn);

とします。 exprnの値が関数が返すものになります。

もし関数内部のある式からreturnしたいなら、 blockreturnを使わなければいけません。

block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)

はそれ自身式で、関数定義の右辺にとって代わることができます。 この際、最後の式よりも早くreturnが起こるかもしれません。

ブロックの中の最初の[]は、 [a: 3, b, c: []]のように、変数と変数割り当てのリストを含むかもしれません。 [a: 3, b, c: []]は、3つの変数a,b,cが コードが、block内部やblock内部からコールされた関数内部で実行される限り、 グローバル値を参照しないように、しかしむしろ特別な値を持つようにします。 変数がブロックの開始から抜ける時間まで続くので、これは、動的バインドと呼ばれます。 一旦blockから戻るか、そこから出ると、(もし存在するなら)変数の古い値が戻されます。 この方法で変数を保護することは確かによい考えです。 ブロック変数に関する割り当ては、並列に行われることに注意してください。 これは、もし先にc: aを使ったら、cの値はブロックにちょうど入った時、まだ aがバインドされる前のaの値であることを意味します。 例えば、

block ([a: a], expr1, ... a: a+3, ..., exprn)

のような何かを実行することは、 aの外部の値を変更されないよう保護しますが、その値がなんだったかアクセス可能にします。 割り当ての右辺は、バインドが起こる前に入る文脈の中で評価されます。 Using just ただblock ([x], ...を使うことは、 ちょうどまるで新しいMaximaセッションに入ったかのように、xがそれ自身を値として持つようにします。

関数の実際の引数は、ブロックの変数と厳密に同じ方法で扱われます。 例えば、

f(x) := (expr1, ..., exprn);

f(1);

では、式の評価に関して、まるで

block ([x: 1], expr1, ..., exprn)

を実行したかのような類似の文脈を持ちます。

定義の右辺がランタイムで計算される時、 関数内部では、defineとたぶんbuildqを使うことが役に立ちます。

Inside functions, when the right hand side of a definition, may be computed at runtime, it is useful to use define and possibly buildq.

36.2.2 Array functions

配列関数は、初めて与えられた引数でコールされた時、関数値を記憶し、 同じ引数が与えられた時、再計算することなしに記憶した値を返します。 そんな関数はしばしばメモ化関数と呼ばれます。

配列関数名は、(グローバルリストfunctionsではなく) グローバルリストarraysに追加されます。

arrayinfoは 記憶された値を持つ引数のリストを返し、 listarrayは記憶された値を返します。 dispfunfundefは配列関数の定義を返します。

arraymakeは、通常の関数に対するfunmakeのように、 配列関数コールを構成します。 arrayapplyは、 通常の関数に対するapplyのように、 配列関数をその引数に適用します。 配列関数に対して、mapに厳密に似たものはありません。 map(lambda([x], a[x]), L)または makelist(a[x], x, L)Lはリストです―は、目的からそれほど遠くありませんけれども。

remarrayは、 通常の関数に対するremfunctionのように、 (記憶された関数値も含めて、)配列関数の定義を削除します。

kill(a[x])は、配列関数aの引数xに関して記憶された 値を削除します; 次回、引数xaがコールされた時、 関数値は再計算されます。 しかしながら、 関数定義も削除するkill(a)またはremarray(a)を除いて、 記憶された値すべてを一度に削除する方法はありません。


Next: , Previous: Introduction to Function Definition, Up: Function Definition   [Contents][Index]