続・凄い人見つけた

回答 (Lispのひび)
早速回答をもらえました。
ありがとうございます。

> でも、Cで書くなら、再帰呼び出しに頼らず、自分でスタックを持った方がいいかもしれません。
これはどういう意味なのでしょうか。うーん、ちょっと分かりません。

私のcygwin上での動作ですが

$ cat test.c
#include <stdio.h>
#include <stdlib.h>
void muda_rec(int n)
{
if (n > 0) {
muda_rec(n - 1);
}
}
int main(int argc, char **argv)
{
if (argc != 2) {
printf("Usage: %s number\n", argv[0]);
return 1;
}
muda_rec(atoi(argv[1]));
printf("hello world\n");
return 0;
}
$ gcc test.c
$ ./a 100000
hello world
$ ./a 1000000
$

再帰呼び出しをやりすぎると動作がおかしくなるのがわかります。
(本来表示されるはずの”hello world”が表示されずにプログラムが終了してます)
mallocなどで大きな配列を確保し、それをスタックとして利用すれば再帰呼び出しを使わずに
ループとしてプログラムを書けるのでこの問題を回避できます。
(もっとも、上のプログラムの場合はスタックを使う必要もありませんが…)
もちろん、配列を使い切るという可能性もありますが、配列のサイズは自分で分かっているため、
使い切った場合はエラーメッセージを出したり、reallocで領域を追加で確保できます。

neg、+-*/関数の実装を終えた。引数列から数値のみ取り出す関数などに分離したら簡潔に書けた。
関数宣言の部分をそのまま引用します。どんな関数が実装されているか分かると思うので。

add_func("quit",	quit,		type_subr);
add_func("car",		func_car,	type_subr);
add_func("cdr",		func_cdr,	type_subr);
add_func("cons",	func_cons,	type_subr);
add_func("eq",		func_eq,	type_subr);
add_func("?atom",	func_isatom,	type_subr);
add_func("==",		func_iseq,	type_subr);
add_func("=",		func_set,	type_fsubr);
add_func("define",	func_define,	type_fsubr);
add_func("neg",		func_neg,	type_subr);
add_func("+",		func_add,	type_subr);
add_func("-",		func_sub,	type_subr);
add_func("*",		func_mul,	type_subr);
add_func("/",		func_div,	type_subr);

(T216の関数)

type_subrとtype_fsubrのあたりに感動しました。結婚してください(笑)
それにしても関数の名前がなんだか独特ですね。
?atom という名前は少し変な気がします。?をつけるなら普通は atom? でしょう。
(ただ、そうするのであれば、 eq も eq? にすべきでしょう。)

関数導入は(define A (B) C)ならアトムAに関数ポインタとして(lambda (B) C)を代入します。タイプはexpr(引数評価型)です。
==関数は内部までしっかり等しいかをチェックします。eqのようにアドレスが同じだけで判断しません。
(T216関数追加)

上の説明を読む限り、defineは関数定義専用なんでしょうか。
それなら普通はdefunという名前を使います(上の引数の使い方もdefunと一致しますし)。
変数と関数の名前空間が同一であれば、Schemeのdefineと同様に、
関数と変数両方の定義に使えると面白いかと思います。
それから、==に関しては、
(== ‘(a b c) ‘(a b c)) => t
ということなんでしょうか。
それならequalという名前を使うのが一般的かと思います。

(eq 'a 'a) => t
(eq 1 1) => 未定義
(eql 1 1) => t
(eql '(a b c) '(a b c)) => 未定義
(equal '(a b c) '(a b c)) => t

といったように、名前が長くなるにつれてチェックが細かくなります。
とにかく、ひとまず完成したようで何よりです。
これからも頑張って下さい。応援してます。

Leave a Reply