Hi Erik,

> I came across a cute little Common Lisp macro, mapeach
> <http://malisper.me/2015/06/14/mapeach/>. Naturally, I wanted it to play
> with it in PicoLisp. The most straightforward translation (for me) of the
> code in the post was:
> 
> [de mapeach "E"    # expression
>    (let [(@Var @List . @Body)  "E"]
>       (macro
>          (mapcar
>             '((@Var) . @Body)
>             @List ]

Yes, that's fine.


An alternative could be

   (de mapeach "Args"
      (mapcar
         (cons (cons (car "Args")) (cddr "Args"))
         (eval (cadr "Args")) ) )

The 'cons'es are a little less expensive than the full macro.


> What are some other ways this could be written? I'm thinking it might be in
> the spirit of do*, as defined in the FAQ

A way in the spirit of do* would be

   (de mapeach "Args"
      (mapcar
         '(("E")
            (bind (car "Args")
               (set (car "Args") "E")
               (run (cddr "Args")) ) )
         (eval (cadr "Args")) ) )

This is a bit longer, but needs no consing at all.



> It works great for single variable expressions.
> 
> : (mapeach N (1 2 3) (* N N))
> -> (1 4 9)
> 
> Multiple vars will make it angry (return NIL).

That's right. But if we define this syntax for multiple variables:

   (mapeach (X Y) '(a b c) '(d e f) (foo ...

we can write

   (de mapeach "Args"
      (let "Vars" (pop '"Args")
         (apply mapcar
            (mapcar eval (cut (length "Vars") '"Args"))
            (cons "Vars" "Args") ) ) )

   : (mapeach (X Y) (1 2 3) (4 5 6)
      (* X Y) )
   -> (4 10 18)

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to