-
-
Save vapniks/5823399 to your computer and use it in GitHub Desktop.
(defun mapcar@ (fun seq) | |
(let (result) | |
(loop for elem in (reverse seq) | |
for newelem = (funcall fun elem) | |
if (and (listp newelem) | |
(eq (car newelem) '@)) | |
do (loop for newelem2 in (cdr newelem) | |
do (setq result (cons newelem2 result))) | |
else do (setq result (cons newelem result))) | |
result)) |
Ah yes, I wasn't aware of -mapcat. Anyway, how about a further generalization for performing the converse of splicing: folding over a subsequence of seq, and emitting the result of the fold (thus returning a single item instead of many). I was thinking of introducing another special symbol, e.g. 'omit, to indicate results to omit. A closure over some accumulator variable could be passed into mapcar@.
An example usage would be great. :)
For example you could use it for counting subsequences:
(mapcar@ '(closure (acc prev) (b)
(cond b
((eq prev nil) (setq prev b acc (cons b acc)))
((eq prev b) (setq acc (cons b acc))
'omit)
(t (prog1 (length acc)
(setq acc nil prev b)))))
seq)
(a a a b b b c d d d) => (3 2 1 3)
Actually, it would also need something to signal the end of the list, and I guess there is probably another mapping function that could do this, but it just seems the logical next step - ragged mapping.
Btw.. how do you get coloured syntax highlighting in your gist?
Actually forget it. Just realized it's probably easier to do it directly with a loop.
Huh, that is a cool idea. This is a case I often encounter, so I definitely see the need. But I am not sure the code looks any better than with mapcat? Here's my example, maybe you have a better one. :)
You have to wrap one of the cases either way. Unless you write functions specifically for use with
mapcar@
that always have a'@
in front, but that seems slightly silly to me.What do you think?