読者です 読者をやめる 読者になる 読者になる

続・継続

前回の追記に書いたmydefをメソッド定義にも使えるように微修正。

mac(mydef)^(name, func):
  _ret := "return_" +
          if (name.parent == Messenger):
            (name.receiver.to_s() + "_" + name.message.to_s())
           else:
            name.to_s()
  _body := Block.new([`(?_ret.intern() := return), *func.body.list])
  _func := Function.new(func.params, _body)
  `def(?name, ?_func)

mydef(findFirstNegative)^(arr):
  arr.foreach^(elem):
    if (elem < 0):
      return_findFirstNegative(elem)
  []

mydef(List.findif)^(f):
  .foreach^(elem):
    if (f(elem)): return_List_findif(elem)
  []

a = [123, 45, -67, 8, -9]
say findFirstNegative(a)  # => -67
say a.findif^(n){ n < 0 } # => -67

それとshift, resetを写経してみた。(ここから)

mac(with_gensyms)^(&rest args):
  syms := args.butlast().map^(sym): `(?sym := Symbol.generate())
  `begin(?Block.new([syms | args.last1().list]))

meta_continuation = ^(v): error("No top-level RESET" + v)

mac(reset)^(body):
  with_gensyms(mc, k, v, result):
    `begin:
      ?mc := meta_continuation
      callcc^(?k):
        meta_continuation = ^(?v):
          meta_continuation = ?mc
          (?k)(?v)
        ?result := begin(?body)
        meta_continuation(?result)

mac(shift)^(func):
  with_gensyms(k, v, result):
    `callcc^(?k):
      ?result := (?func)^(?v): reset: (?k)(?v)
      meta_continuation(?result)

say([1] + reset{[2] + shift^(k){ [3] + k([4]) } + [5] })
 # => [1, 3, 2, 4, 5]
say([1] + reset{ shift^(k){ [2] + k([3]) } + shift^(k){ [4] + k([5]) } + [6] })
 # => [1, 2, 4, 3, 5, 6]

で、次はどうすればいいんだっけ… srfi-41の移植か(違