自由変数の決定
schemeのマクロを勉強している時に、
1 (define-syntax mcr 2 (syntax-rules () 3 ((_) (print var)))) 4 5 (define (fnc) (print var)) 6 7 (define var 2) 8 (mcr) 9 (fnc) 10 (set! var 3) 11 (mcr) 12 (fnc)
の実行結果が、
2 2 3 3
なのが衝撃だった。関数定義でも自由変数が使えて、その自由変数は実行時の環境で中身が決定するみたい。ちなみに、他の言語ではどうかと試してみると、Cでは、(clingを使用)
int fnc() { printf("%s", var); return 0; }
と関数を定義しようとすると、
input_line_4:2:14: error: use of undeclared identifier 'var' printf("%s", var);
と怒られた。しかし、pythonでは、(ipythonを使用)
def fnc(): print(var) var = 1 fnc() #=> 1
となった。なんと、pythonでも同じようなことができるのだ。
まあ、関数の定義時には、自由変数が何であれ関係ないといえば、その通りなのだが、今まで出くわしたことがなかったのでちょっと驚いた。
訂正
Cでも、(clingを使用)
int var = 2; int fnc() { printf("%s", var); return 0; }
と関数を定義すると、エラーにならない。どうやら、関数定義時に自由変数が宣言されていなければならないようだ。