(def codetree (file)
(trav + 1 (readall (infile file))))
Anything that appears after two newlines and a blank space is treated as code, till there's a line that doesn't begin with a space. This is like the markdown convention, but you don't have to use four spaces; one will do.Incidentally, the code above tells me the number of nodes in the code tree of a file. Not just leaves, which would be
(len (flat (readall (infile file))))
but interior nodes as well. To me this is the best measure of how long a program is. I used to go by lines of code (def codelines (file)
(w/infile in file
(summing test
(whilet line (readline in)
(test (aand (find nonwhite line) (isnt it #\;)))))))
but I found this was encouraging me to do the wrong things.(This kind of test matters because I'm constantly trying to make news.yc shorter as a way of pushing functionality down into Arc.)
Here's trav, btw:
(def trav (f base tree)
(if (atom tree)
(base tree)
(f (trav f base (car tree)) (trav f base (cdr tree)))))
It traverses a tree, doing something at every node. So e.g. CL copy-tree would be (def copy-tree (tree) (trav cons (fn (x) x) tree))
If you're wondering how the second argument to trav in codetree could be 1, it's because a constant when called as a function simply returns itself. This turns out to be quite handy.In On Lisp, you mentioned that implementing continuations with closures via transformation to CPS could be accomplished by writing a code walker, but that this would be a "serious undertaking" in Common Lisp.
This struck me at the time and ever since as painful, but understandable. Macros aren't first-class objects in CL, so the code you're walking through could be very complex due to macro-expansion, and I could be wrong, but I don't remember if the resulting code would necessarily contain clues that tell us what macro generated it, etc.
Could one assume (and it is definitely an assumption, or speculation, not a deduction from what you've given us here!) that it would be much simpler in Arc? Say, a page or so of code?