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

このように動くのを見たところ、関数内部における変数への参照があると、
定義された環境から外の環境に向かって、順番に変数を探すように思えるんですが、
引数の場合だけ何か扱いが違うんですかね。
ローカル変数の取り扱いの説明が、この記事だけだと、分からないところが多いので、
出来れば詳しい説明をお願いします。

One Response to “Cyan”

  1. takuto_h より:

    > 何故か無限ループに陥ってしまいます。
    Cyanのバグでした。ご指摘ありがとうございます。
    お知らせするのが遅れて申し訳ありません。

Leave a Reply