Function (Maxima 5.46.0 Manual)

Next: Macros, 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`したいなら、 `block`と`return`を使わなければいけません。

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

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

ブロックの中の最初の`[]`は、 `[a: 3, b, c: []]`のように、変数と変数割り当てのリストを含むかもしれません。 `[a: 3, b, c: []]`は、３つの変数`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`は記憶された値を返します。 `dispfun`と`fundef`は配列関数の定義を返します。

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

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

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

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