Arc Forumnew | comments | leaders | submitlogin
7 points by pg 6124 days ago | link | parent

Since captured symbols are kind of freaky I want to be conservative with names: it for objs in general, and self for fns. I wouldn't want to use trav in case someone actually wants to call trav in one of the arguments.


4 points by almkglor 6124 days ago | link

Well, "self" has attached itself (in my mind, anyway) to afn. Seeing "trav" use "self" is disturbing - its like "self" is an unfaithful wife or something.

"self" for "afn" is OK, because "afn" is defined as "a function which calls itself". It's not so OK for "trav", because "trav" doesn't call "itself" (yes, internally it does, but for the user of the macro, it isn't - it's traversing a structure). That's why I'd rather suggest using go. Or alternatively have an optional "go" argument:

  (mac trav (struct . body)
    (with
         (
           gofn (if (isa (car body) 'sym) (car body) 'self)
           fns (if (isa (car body) 'sym) (cdr body) body))
    (w/uniq g
      `((rfn ,gofn (,g)
          (when ,g
            ,@(map [list _ g] fs)))
        ,x))))
So:

  (trav b go [go _!l] [a _!d] [go _!r])
or:

  (trav b [self _!l] [a _!d] [go _!r])
Of course this has the problem where the user might have an existing named function that he or she just wants to call to handle some part of the structure:

   (trav b existing-fun [self _!next])
A possible alternative would be to force the user to add a ' to the gofn symbol. Since symbols cannot be applied (yet), it would unambiguously specify a special symbol to replace the default 'self:

  (mac trav (struct . body)
    (withs
         (
           is-quote-form [caris _ (car ''x)]
           quote-form-var cadr
           gofn
           (if (is-quote-form (car body))
              (quote-form-var (car body))
              'self)
           fns
           (if (is-quote-form (car body))
              (cdr body)
              body))
    (w/uniq g
      `((rfn ,gofn (,g)
          (when ,g
            ,@(map [list _ g] fs)))
        ,x))))
Then I could either use:

  (trav b [self _!l] [a _!d] [self _!r])
or:

  (trav b 'go [go _!l] [a _!d] [go _!r])
A final alternative is to imitate 'rfn and 'afn: define 'rtrav which requires a symbol for the "go" action, and 'atrav which specifically uses 'self.

-----

4 points by almkglor 6124 days ago | link

Yet another alternative:

   (mac trav ((go v) s . body)
      `((rfn ,go (,v)
            ,@body)
        ,s))

   (trav (go node) b
      (go node!l)
      (a node!d)
      (go node!r))
The above is arguably lispier, and removes the need for [] everywhere.

-----

1 point by almkglor 6123 days ago | link

Bugged, of course ^^ Forgot the (when ...) test.

   (mac trav ((go v) s . body)
      `((rfn ,go (,v)
            (when ,v
              ,@body))
        ,s))

-----