Hmm, I wonder if each is a good way to encode the lazy-list conversion. Perhaps it makes sense to make each generic, and map just use each.
Feels a bit like you missed my point. Just in case, it was:
1. Make 'some, 'fn-ifdecap, and 'as-lazy-list generic.
; 'defgeneric versions
(some (fn (x) <test>) xs)
(fn-ifdecap (fn (x xs) <split case>) (fn () <empty case>) xs)
(as-lazy-list (fn (lazy-orig) <lazy result>) orig)
; the versions I currently have in my Penknife core library draft
[fn-any xs [fn [x] <test>]]
[fn-ifdecap xs [fn [x xs] <split case>] [fn [] <empty case>]]
[fn-decap-erism orig [fn [lazy-orig] <lazy result>]]
; I'll probably rename this to "call-as-seq".
; A "decap-er" is something that has fn-ifdecap behavior.
2. Base utilities like 'ifdecap (a macro), 'all, 'each, and 'map off of these.
The version of 'map in my draft is something like this:
[fun fn-map [seq func]
[rely:decap-erism lazy-seq seq
[nextlet rest lazy-seq ; aka xloop, or named let
[make-decap-er:fn [then else]
[ifdecap first rest rest
[then func.first next.rest]
else.]]]]]
No 'each is required, just 'fn and 'xloop. :) And the 'xloop is just there to keep from bothering with conversion when recurring on the tail.
Aside: The "rely" here is supposed to make the result of fn-map undefined if the result of decap-erism is undefined. That part probably isn't easy to translate to Arc; I essentially have an extra implicit parameter in every Penknife function call, specifying what to try instead if the call is rejected. It's kind of a tacked-on thing, and I'd avoid it if I had some better idea, but it seems to help immensely with writing extensible utilities.