Cyanで遊ぶ
Cyan, Yet Another New language - takuto_hの日記
S式じゃないのにLispと同等のマクロが書ける。すげー。
とりあえず遊ぶためにユーティリティーをいくつか。
### macros
mac(Object.equal)^(obj):
`(((?self).parent == (?obj).parent) && (?self == ?obj))
mac(recur)^(name,func):
`let^(&opt ?name = ?func):
(?name)()
mac(assert)^(exp):
`aif (?exp) { it } else { error "failed: " + ?(exp.to_s()) }
mac(debug_print)^(exp):
say "#?= " + exp.to_s()
result := Symbol.generate()
`let^(&opt ?result = (?exp)):
say "#?- " + (?result).to_s()
?result
### Number
def(Int.mod)^(n): .(-)(.(/)(n)*n)
### List
def(List.car)^: [] # [].car() -> []
def(List.cdr)^: [] # [].cdr() -> []
def(List.ncdr)^(n):
if (n <= 0 || .null?()):
self
else:
.cdr().ncdr(n - 1)
def(List.subseq)^(a, &opt b):
.ncdr(a).take((b || .length())- a)
def(List.position)^(e, &opt o = 0):
cond:
(.null?()):
[]
(e.equal(.car())):
o
else:
.cdr().position(e, o + 1)
def(List.each)^(fn, &opt i = 0):
unless(.null?()):
fn(i, .car())
.cdr().each(fn, i+1)
def(List.join)^(&opt sep = ""):
.cdr().foldl(.car().to_s(), ^(acc, e){ acc + sep + e.to_s() })
### String
def(String.to_list)^:
let^(&opt s = .istring(), l = []):
awhile(s.readc()): push!(l, it)
l.reverse()
def(String.char)^(i):
#.to_list()[i]
s := .istring()
i.times: s.readc()
s.readc()
def(String.subseq)^(start, &opt end):
.to_list().subseq(start,end).join()
def(String.split)^(sep):
if (sep == ""):
.to_list()
else:
let^(&opt s = .istring(), l = [], acc = ""):
awhile (s.readc()):
if (it == sep):
push!(l,acc)
acc = ""
else:
acc += it
push!(l, acc).reverse()10.mod(3)を10 mod 3って書ける様にするにはどうすればいいんだろ?
そしてλ計算遊びしようと思ったらはまった。
c2 = ^(f): ^(x): f(f(x)) inc = ^(n): n + 1 c2(c2)(inc)(0)
これが無限ループになっちゃうみたいで帰ってこない。
c2 = ^(f): debug_print(f); ^(x): debug_print(x); f(f(debug_print(x)))
debug_print(c2(say)("w"))
debug_print(c2(c2)(say)("w"))実行
#?= c2(say)("w")
#?= f
#?- #<subr say>
#?= x
#?- w
#?= x
#?- w
w
w
#?- w
#?= c2(c2)(say)("w")
#?= f
#?- ^(f){ debug_print(f); ^(x){ debug_print(x); f(f(debug_print(x))) } }
#?= x
#?- #<subr say>
#?= x
#?- #<subr say>
#?= f
#?- #<subr say>
#?= f
#?- ^(x){ debug_print(x); f(f(debug_print(x))) }
#?= x
#?- w
#?= x
#?- w
#?= x
#?- w
(中略)
#?= x
#?- w
^Cバッチ ジョブを終了しますか (Y/N)? Yよくわかんね。もうちょっと調べてみよう。
直してもらえた
_? = debug_print
c2 = ^(f): _?(f); ^(x): _?(x); f(f(_?(x)))
_?(c2(c2)(say)("w"))結果
#?= c2(c2)(say)("w")
#?= f
#?- ^(f){ _?(f); ^(x){ _?(x); f(f(_?(x))) } }
#?= x
#?- #<subr say>
#?= x
#?- #<subr say>
#?= f
#?- #<subr say>
#?= f
#?- ^(x){ _?(x); f(f(_?(x))) }
#?= x
#?- w
#?= x
#?- w
#?= x
#?- w
#?= x
#?- w
w
w
#?= x
#?- w
#?= x
#?- w
w
w
#?- w
=> trueよーし後はマクロを書きまくれば・・・