[Bese-devel] <ucw:a

Marco Baringer mb at bese.it
Thu Nov 3 15:15:00 UTC 2005


Bill Atkins <atkinw at rpi.edu> writes:

> On 11/2/05, Marco Baringer <mb at bese.it> wrote:
>> Jan Rychter <jan at rychter.com> writes:
>>
>> > So, can I generate (<ucw:a :action (myaction p)) links inside looping
>> > constructs with p bound successively to various values? If so, which
>> > looping constructs are supposed to work?
>>
>> any looping construct which creates a fresh binding on each iteration
>> (since P is a closed over variable successive loops which change the
>> value of p will change it for all the links generated).
>>
>
> Can you explain this a little more?

you first need to know a little bit more about how <ucw:a
works. <ucw:a is a macro which expands into something like this
(edited for clarity):

  (<ucw:a :action (foo bar) ...)

  (<:a :href (register-action (lambda () (foo bar))) ...)

so the form passed to :action is nothing more than a closure. problems
can arise with code like this:

  (dolist (i a-list)
    (<ucw:a :action (do-something i)))

which, on most lisps, macro expands to (edited for clarity) this:

  (let (i)
    (tagbody
      loop
        (setf i (pop a-list))
        (<ucw:a :action (do-something i))
        (if (endp a-list)
            (go done)
            (go loop))
      done))

So the variable I used in the action closures is modified on each
iteration of the loop. the effect of this is that, when the loop is
done looping and the html has been generated, each closure closes over
I but has the same value in all closures :(

the solution is to not use the same binding for each closure but to
generate a new one on each iteration:

  (dolist (i a-list)
    (let ((the-closed-over-variable i))
      (<ucw:a :action (do-something the-closed-over-variable))))

now each closue will get its own the-closed-over-variable whose value
will be the value of I at that particular iteration, since bindings
are different than the names of variabels we can replace the above
with this:

  (dolist (i a-list)
    (let ((i i))
      (<ucw:a :action (do-something i))))

which is exactly what dolist* expands to :)

hth.

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen



More information about the bese-devel mailing list