Miles Bader <[EMAIL PROTECTED]> writes:
> I assume the _reason_ for this practice is an attempt to avoid dynamic
> binding problems with variables bound in the caller and used by the
> lambda expressions, but while this is a real issue, it's easy enough to
> work around in vaguely ugly ways (e.g., just use normal binding and
> give the potentially problematic variables names that are unlikely to
> conflict; I sometimes prepend the name of the caller for this purpose,
> e.g.,
>
> (defun my-funny-function ()
> ...
> (let ((my-funny-function-var1 ...))
> (use-my-lambda (lambda () ... my-funny-function-var1 ...))))
It's not so much about avoiding conflicts with the caller, as simulating
some sort of lexical closure. The problem is that we want define a
callback function (one of these lambdas) that retains values that were
in scope when it was defined.
For example, tla-start-project reads a directory from the user and calls
`tla import'. We want to run the tla command asynchronously, but when
it's finished we would also like to run `tla inventory' in the directory
entered by the user. The corresponding code looks like:
(defun tla-start-project (&optional archive)
(interactive)
(let* ((base (tla--read-directory-name "Directory containing files to
import: "
(or default-directory
(getenv "HOME"))))
[...])
[...]
(tla--run-tla-async
(list "import" "--setup")
:finished
`(lambda (output error status arguments)
(tla-inventory ,base t)))
[...]))
Without the backquote, we'd have to arrange to make the value of `base'
available by some other means. Run-time expansion of CL macros is
something I'd not considered, but that should probably be fixed.
Is there some easier way of doing this that we're missing? I know ERC
uses this technique in a couple of places, so I'm not (quite) a lone
crackpot ;o)
Mark
--
Mark Triggs
<[EMAIL PROTECTED]>