Arc Forumnew | comments | leaders | submitlogin
4 points by rocketnia 5314 days ago | link | parent

You could do a couple of things.

If it's just one self-recursive function, use 'afn or 'rfn:

  (let factorial (afn (x)
                   (if (is x 0)  0
                       (< 0 x)   (self:- x 1)))
    factorial.12)
  
  (let factorial (rfn custom-name (x)
                   (if (is x 0)  0
                       (< 0 x)   (custom-name:- x 1)))
    factorial.12)
(Note that 'afn is just 'rfn with the name 'self already chosen for you.)

If one local function just needs to refer to another, you can use 'withs:

  (withs (get-street [...]
          format-address [... get-street._ ...])
    ...)
I doubt that's what you're looking for though, 'cause it's just a convenience for doing this:

  (let get-street [...]
    (let format-address [... get-street._ ...]
      ...))
If it's two or more actually corecursive functions you need, you can use a manual letrec pattern. (Is CL's 'labels basically the same as Scheme's 'letrec?)

  (let (odd even) nil     ; destructuring, so both start as nil
    (= odd [case _ 0 nil (even:- _ 1)])
    (= even [case _ 0 t (odd:- _ 1)])
    odd.12)
In fact, if you're using Anarki (http://github.com/nex3/arc), this kind of letrec is already defined as 'withr:

  (withr (odd [case _ 0 nil (even:- _ 1)]
          even [case _ 0 t (odd:- _ 1)])
    odd.12)
...I really like reducing parentheses though, so just now I added my own 'letrec to Lathe (http://github.com/rocketnia/lathe). :-p

  (use-rels-as ut (+ lathe-dir* "utils.arc"))
  
  ; The bindings all have to be everyday variable names, but this
  ; detects them automatically. You can use with-style parentheses too,
  ; in case you need to be extra sure.
  (ut:letrec odd [case _ 0 nil (even:- _ 1)]
             even [case _ 0 t (odd:- _ 1)]
    odd.12)