[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Faking local dynamic function bindings
From: |
Joost Kremers |
Subject: |
Re: Faking local dynamic function bindings |
Date: |
29 Jan 2014 09:05:23 GMT |
User-agent: |
slrn/pre1.0.0-18 (Linux) |
EN:SiS(9)
Stefan Monnier wrote:
>> (defun foo (sexpr)
>> (eval
>> `(cl-macrolet ((contains (regexp)
>> `(string-match ,regexp string)))
>> (sort (delq nil (mapcar #'(lambda (item)
>> (let ((string (assq item strings-alist)))
>> (when ,sexpr)
>> string))
>> items-alist))
>> 'string<))))
>
> IIUC, sexpr is only known very late (like much later than when you
> byte-compile this file).
Yes, you understand correctly.
> If that's the case, there's no avoiding `eval'.
This is the point where I hit myself over the head and say duh... That
should have been obvious, even to me.
> But you can move the eval closer to sexpr:
>
> (defun foo (sexpr)
> (sort (delq nil (mapcar #'(lambda (item)
> (let ((string (assq item strings-alist)))
> (when (eval
> `(cl-macrolet ((contains (regexp)
> `(string-match
> ,regexp ,string)))
> ,sexpr))
> string))
> items-alist))
> #'string<)))
This resembles an earlier version of my code, but AFAIU it has the
disadvantage that the local macro binding is created and destroyed every
time the anonymous function is executed, which I guess creates extra
overhead and makes the function slower. That's why I moved the
cl-macrolet outside the mapcar. (Though I haven't done any profiling and
the older version was fast enough not to be annoying...)
> And of course, you don't need `contains' to be a macro:
True, of course. However, I'm using a macro because in the actual code
one of the arguments of `contains` is an unquoted symbol. (That's an
unfortunate design decision I made years ago that has proven to be
completely pointless and impractical. I've been meaning to change it,
but haven't found the time to do so yet.)
Thanks,
Joost
--
Joost Kremers joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht