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

よーし後はマクロを書きまくれば・・・