Arc Forumnew | comments | leaders | submitlogin
2 points by skenney26 5757 days ago | link | parent

(With very minimal testing)

  (mac mrec (fns . body)
   `(let (,@(map1 car fns)) nil
      ,@(map1 (fn (f) `(def ,@f))
              fns)
      ,@body))

  arc> (mrec ((f1 () (prn "bob") (f2))
              (f2 () (prn "bib") (f1)))
         (f1))
  bob
  bib
  bob
  bib
  ...


3 points by rntz 5755 days ago | link

This won't work if you want to define a function called 'o. Reason: (let var val ...) becomes ((fn (var) ...) val), and if var is (o ...), it becomes ((fn ((o ...)) ...) val). (o ...) is interpreted as an optional parameter, which disables destructuring.

Destructuring in lets is a nice idea, and using this with nil is a cool hack, but until and unless this behavior is changed, don't rely on it in macros - it can cause unexpected code breakage. A better way to do it would be the following (my 'fwithr is your 'mrec).

    (mac withr (bindings . body)
      (let bindings (pair bindings)
        `(with ,(mappend [list car._ nil] bindings)
           ,@(mapeach b bindings
               `(set ,@b))
           ,@body)))

    (mac fwithr (fns . body)
      `(withr
         ,(mappend [list car._ `(fn ,@cdr._)] fns)
         ,@body))
Edit: It seems almkglor has already done something like this, but his also has the "let doesn't always destructure" bug: http://arclanguage.org/item?id=7387

-----