By the way, I think I said elsewhere that I've been rewriting arc.arc and cleaning it up a little. I have been paying attention to the comments, so if anything is a little messy but runs 3x as fast as the clean way, I'm leaving it as is.
Anyway, one of the comments is that, while iso takes 2 args now, it really should take n args. Here's what I came up with:
I don't like the list concatenation idea, but I think the Church encoding idea, while maybe not good per se, is at least interesting and perhaps worth considering.
Really? I thought easy list concatenation was the better idea. Arc is a list-based language, and concatenation is a very basic list operation, so I thought it would be a good thing to optimise it as much as possible.
Basically, as long as it has a termination condition that is always reached, it works. For example (this may not match arc.arc as I'm making this up on the spot):
(mac aif (test . body)
(if body
`(let it ,test
(if it
,(car body)
(aif ,@(cdr body))))
test))
Now, let's expand this (I won't bother expanding let, just aif):
(aif a b c d e)
; expand aif
(let it a
(if it
b
(aif c d e)))
; expand aif
(let it a
(if it
b
(let it c
(if it
d
(aif e)))))
; expand aif
(let it a
(if it
b
(let it c
(if it
d
e))))
If you feed in an even number of terms, this happens:
(aif a b)
; expand aif
(let it a
(if it
b
(aif nil)))
; expand aif
(let it a
(if it
b
nil))
That works because (car nil) is nil. Convenient!
Also, I'm something of a perfectionist, and sometimes when I get bored I've been cleaning up some of the macros in arc.arc. I've been able to work out cleaner implementations that produce cleaner expansions for some of them. For example, I don't know why while is implemented as: