 I've been meaning to write this up for a while, putting together some examples of how this is useful. But each time I go to think about it, I second guess myself as to whether this brings anything new to arc. Do we already have mutually recursive local functions? In any case, here is the labels macro ported to arc from common lisp. I'd appreciate comments on whether or not we can already do everything offered by labels. (def caddr (x)
(car (cdr (cdr x))))
(def flet2fn (flet)
(with (name (car flet)
args (cadr flet)
body (caddr flet))
`(,name (fn ,args ,body))))
(mac labels (fns . forms)
(withs (fnames (map car fns)
nfnames (map [uniq] fnames)
nfbodies (map (fn (f) `(fn ,@(cdr f))) fns))
`(with ,(mappend (fn (nf) `(,nf (fn () ()))) nfnames)
(with ,(mappend (fn (f nf) `(,f (fn a (apply ,nf a))))
fnames nfnames)
(with ,(mappend flet2fn fns)
(do ,@(map (fn (f nf) `(= ,nf ,f))
fnames nfnames))
,@forms)))))
I grabbed the common lisp implementation from here: http://www.pipeline.com/~hbaker1/MetaCircular.htmlExample usage: (def collatzseq (n)
(labels ((collatz (n)
(if (even n)
(/ n 2)
(+ (* n 3) 1)))
(worker (n seq)
(if (is n 1)
(cons n seq)
(worker (collatz n) (cons n seq)))))
(rev (worker n '()))))
(collatzseq 10)
;; mpr@mpr:~/src/arc$ arc collatz.arc
;; (10 5 16 8 4 2 1)
;; #t
