[ ] で再帰

ふと思い立って、以前Arcを真似て書いた無名関数リーダーを再帰できるようにしてみた。
良い記号が思い付かないのでとりあえず ^ で。
xyzzy-lisp/brackets.l at master · youz/xyzzy-lisp · GitHub

(defun bracket-reader (stream char)
  (declare (ignore char))
  (let ((^ (intern "^")) (_ (intern "_")))
    `(lambda (#0=#:_)
       (labels ((,^ (,_) ,(read-delimited-list #\] stream t)))
	 (,^ #0#)))))

Arcの場合はbrackets.scmの15行目の (fn (_) を (rfn ^ (_) とか (afn (_) とかにするだけで良いのでお手軽簡単。

使用例 (fibonacci とflatten)

> ([if(< _ 2) _ (+ (^ (- _ 1)) (^ (- _ 2)))] 25)
75025

> ([if (consp _) (mapcan #'^ _) (list _)] '(1 2 (3 4 (5)) ((6 7))))
(1 2 3 4 5 6 7)

Arcでのgolf例 anarchy golf - Collatz Problem

;; before
((= c[c:if(< prn._ 2)$ odd._(+(* _ 3)1)(/ _ 2)])(read))

;; after
([^:if(< prn._ 2)$ odd._(+(* _ 3)1)(/ _ 2)](read))

果たしてどれだけ使う機会があるか。*scratch*で使われた回数をどうにかして記録してみようかな。