[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lexical binding

From: Stefan Monnier
Subject: Re: Lexical binding
Date: Mon, 04 Apr 2011 12:22:14 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

>>> (loop for (nil width . nil) in bs-attributes-list
>>> if (numberp width) sum width)
>> Yes, but it is less informative.

BTW, I believe part of the problem is that the loop macro will use
something of the form

  (let (var)
    (while ...
      (setq var ...)

instead of

  (while ...
    (let ((var ...))

The former is likely to bump into the current problem, while the second
isn't.  The former is popular in Elisp because it's slightly faster, but
with lexical scoping the second is actually more efficient.  This is in
part because a lexical `let' is cheaper so it can be moved into the loop
without problems, and in other part because the second form avoids some
more costly cases:

let's take `dotimes' as an example.  What should

  (let ((res ()))
    (dotimes (i 3) (push (lambda () i) res))

return?  Clearly it will be a list of 3 functions, each one taking
0 args and returning a number, but what should the exact return value
be?  With the let-while-setq form of the loop, you'd get three times the
same function returning 3, whereas with the while-let form you'd get
functions returning 2, 1, and 0.

To get the first result, you need to make sure all three functions refer
to some memory cell holding the value of the variable `i', so you get an
extra indirection.  I also find the second behavior more desirable.
So I've changed the dotimes (and dolist) macros to use the while-let
instead of let-while-setq form when used with lexical scoping.

Maybe we should do the same for loop, but I'm definitely not going to
take on this challenge.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]