Alex,

Thanks for the write-up! It's fun to dissect the different versions with
'debug' and mess around at the repl.


> 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.
>

Yes, makes sense. If I understand correctly, you're explicitly stating what
my call to 'macro' eventually builds, but by skipping 'macro' you bypass
the associated calls to 'pat?', 'fill', and 'run'.


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.
>

Awesome! I'm starting to grasp the 'bind', 'set', 'run' combo. This style
makes a lot more sense now that I see it with a simpler function. I'm not a
fluent 'do*'er.


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)
>

Now you're just showing off :) Seriously cool, though.

Reply via email to