ブロックを用いた関数定義
関数定義の際に、関数内でのみ有効なローカル変数を使用したいことがあります。 そのようなときに、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 を判定する関数.