ブロックを用いた関数定義

関数定義の際に、関数内でのみ有効なローカル変数を使用したいことがあります。 そのようなときに、block は便利です。

使用方法

次の形で利用します。

f(引数):= block([ローカル変数],式,...,式)

「最後の式」がとる値がf()の返り値になります。あるいは return(式) として明示的に戻り値を設定できます。

注1:C言語のように return 1 のようには書けません。return (1) のように丸カッコが必要です。

注2:C言語のように return すれば関数が終了するとは限りません。blockが二つ入れ子になっていた場合、 内側のblockでreturnすると内部のブロックから抜けるだけで、全体のblockを抜けることにはなりません。 また、forでも同じです。2重ループになっていたとしたら、内側のforでreturnを使っても全体のループから抜けることにはなりません。

注2の例.

block(
    block(
        return(1)
    ),
    return(2)
);

実行結果

2

注2の例2.

for i thru 10 do (
    for k thru 10 do(
        a:1,
        return(1)
    ),
    a:2
)$
print("a =",a)$

実行結果

a = 2

例(1つのローカル変数xを利用.)

f():=block([x:1],x)$
f();

実行結果. 1

例(上のプログラムで return を使用して明示的に戻り値を設定)

f():=block([x:1],return(x))$
f();

実行結果. 1

例(2つのローカル変数xとyを利用.)

f():=block([x:1,y:2],x+y)$
f();

注:最後の x+y が f の戻り値になっています。

実行結果. 3

例(引数xとローカル変数aを利用.)

f(x):=block([a:0],a:1,x+a)$
f(2);

実行結果. 3

リストを引数にとる関数

リストを引数に取り、いろいろな値を計算する関数の定義例をまとめます。

例(リストの和を計算する関数)

f(list):=
block(
    [sum:0],
    for i in list do sum:sum+i,
    return(sum)
)$
f([1,2,3]);

実行結果. 6

例(3で割って1余る要素の個数を計算する関数)

f(list):=
block(
    [c:0],
    for i in list do 
       if mod(i,3) = 1 then c:c+1,
    return(c)
)$
f([2,3,5,7,11,13]);

実行結果. 2

例(引数のリストの要素が偶数である個所を0で、奇数である箇所を1で置き換えたリストを返す関数)

f(list):=
block(
    [lt:[]],
    for i in list do 
    if evenp(i) then lt:endcons(0,lt)
    else lt:endcons(1,lt),
    return(lt)
)$
f([3,1,4,1,5,9,2]);

実行結果. [1,1,0,1,1,1,0]

Note. evenp(i)はiが偶数かどうかを判定する関数.

文字列を引数にとる関数

例(aとbからなる文字列wordに対して、aは0に、bは1に置き換えたリストを返す関数.)

f(word):=block(
    [list:[]],
    for i:1 thru slength(word) do(
      st:charat(word,i),
      if sequal(st,"a") then list:endcons(0, list)
      else if (sequal(st,"b")) then list:endcons(1,list)
    ),
    return(list)
)$
f("ababaaa");

実行結果. [0,1,0,1,0,0,0]

Note. charat(word,i)は文字列 word の i番目の要素. sequal(word1,word2)は word1=word2 を判定する関数.