Skip to content

Instantly share code, notes, and snippets.

@vapniks
Created June 20, 2013 14:50
Show Gist options
  • Save vapniks/5823399 to your computer and use it in GitHub Desktop.
Save vapniks/5823399 to your computer and use it in GitHub Desktop.
A mapping function that allows splicing lists into the result. If fun returns a list whose first element is @ the following elements will be spliced into the list.
(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))
@magnars
Copy link

magnars commented Jun 21, 2013

An example usage would be great. :)

@vapniks
Copy link
Author

vapniks commented Jun 21, 2013

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?

@vapniks
Copy link
Author

vapniks commented Jun 22, 2013

Actually forget it. Just realized it's probably easier to do it directly with a loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment