Cyan
若干流行に乗り遅れた感じはありますが、
Cyanを触ってみました。
色々気になったけど、時間が無いから一点だけ。
関数の中で関数を作れるのか試してみたんですが、
def(reverse)^(lst): iter:=^(lst2, acc): say(lst2) if (lst2.null?()): acc else: iter(lst2.cdr(), [lst2.car()|acc]) iter(lst, []) reverse([1,2,3,4,5]) # => [5, 4, 3, 2, 1] # 出力されるのは # [1, 2, 3, 4, 5] # [2, 3, 4, 5] # [3, 4, 5] # [4, 5] # [5] # []
これは上手く動きますが、
次のコードだと、
def(reverse)^(lst): iter:=^(lst, acc): say(lst) if (lst.null?()): acc else: iter(lst.cdr(), [lst.car()|acc]) iter(lst, []) reverse([1,2,3,4,5]) # => (無限ループで結果出ず) # 出力されるのは # [1, 2, 3, 4, 5] # [2, 3, 4, 5] # [2, 3, 4, 5] # [2, 3, 4, 5] # [2, 3, 4, 5] # ...(以下同様)...
何故か無限ループに陥ってしまいます。
iterに代入される関数の参照してる「lst」が外側のlstかとも思ったんですが、
一度だけはCDRが取れてるし、そういう仕様でもなさそう。
試しにこんなコードを動かしてみたんですが、
m=100 def(f1)^(): i:=^(n): say(n+m) i(1) m:=3 i(1) m:=2 i(1) f1() # 出力されるのは # 101 # 4 # 3
このように動くのを見たところ、関数内部における変数への参照があると、
定義された環境から外の環境に向かって、順番に変数を探すように思えるんですが、
引数の場合だけ何か扱いが違うんですかね。
ローカル変数の取り扱いの説明が、この記事だけだと、分からないところが多いので、
出来れば詳しい説明をお願いします。
> 何故か無限ループに陥ってしまいます。
Cyanのバグでした。ご指摘ありがとうございます。
お知らせするのが遅れて申し訳ありません。