On Mon, Nov 08, 2004 at 05:16:28PM +1100, Mark Triggs wrote:
> 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.

I see...

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

Hmmm, you might consider using a backquoted wrapper only for binding, and
making the bulk of the lambda compilable, e.g., instead of:

  (function-that-uses-lambda-later
    `(lambda (args) (complicated code... ,variable)))

use:
  
  (function-that-uses-lambda-later
    `(lambda (args)
       (let ((variable ,variable))
         (funcall ,(lambda () (complicated code... variable))))))

You could even make a macro to do this, like:

   (defmacro lambda-with-constant-bindings (constants args &rest body)
     "Like `lambda', with constant bindings for variables in CONSTANTS.
   Any references in BODY to a variable listed in CONSTANTS will evaulate
   to the binding in effect when the lambda was created, rather than at
   the time it is called."
     ``(lambda ,',args 
         (let (,,@(mapcar (lambda (var) ``(,',var ',,var)) constants))
           (funcall ,(lambda () ,@body)))))

Here's an example of use:

   (eval-when-compile (require 'cl))

   (defvar test-var nil)

   (defun test ()
     (let ((a 0) (b 'x) (c 42))
       (lambda-with-constant-bindings (a b c) (x y)
          (setf test-var (list a b c x y)))))

If you compile this, and load it into a fresh-emacs, it seems to do the right
thing:

   (funcall (test) 1 2)
   => (0 x 42 1 2)

[and `cl' still isn't loaded.]

-Miles
-- 
I'm beginning to think that life is just one long Yoko Ono album; no rhyme
or reason, just a lot of incoherent shrieks and then it's over.  --Ian Wolff

Reply via email to