[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Lambda expression inside loop

lalohao

5/30/2016 11:11:00 AM

Hello comp.lang.lisp

I am trying to create some widgets with cl-gtk

The following code fails to pass the variable to the nested expression, i get the following messages instead of the numbered buttons:

Pressed -1.
Released -1.
Pressed -1.
Released -1.
Pressed -1.
Pressed -1.
Pressed -1.
Pressed -1.
Released -1.
Released -1.
Pressed -1.
Released -1.

Code:

(defmacro connect (widget fn)
`(g-signal-connect ,widget "toggled" ,fn))

(loop for n from 8 downto 0 do
(connect (checkbox :expand nil)
(lambda (widget)
(if (gtk-toggle-button-active widget)
(format t "Pressed ~s.~%" n)
(format t "Released ~s.~%" n))))))

Am i missing something fundamental?
Thanks in advance
5 Answers

Jim Newton

5/30/2016 12:33:00 PM

0

On Monday, May 30, 2016 at 1:11:20 PM UTC+2, Eduardo V. wrote:

> (loop for n from 8 downto 0 do
> (connect (checkbox :expand nil)
> (lambda (widget)
> (if (gtk-toggle-button-active widget)
> (format t "Pressed ~s.~%" n)
> (format t "Released ~s.~%" n))))))
>
> Am i missing something fundamental?
> Thanks in advance

what happens if you change to the following?

(loop for n from 8 downto 0 do
(connect (checkbox :expand nil)
(let ((n n))
(lambda (widget)
(if (gtk-toggle-button-active widget)
(format t "Pressed ~s.~%" n)
(format t "Released ~s.~%" n)))))) )

lalohao

5/30/2016 5:43:00 PM

0

El lunes, 30 de mayo de 2016, 7:33:15 (UTC-5), Jim Newton escribió:
> On Monday, May 30, 2016 at 1:11:20 PM UTC+2, Eduardo V. wrote:
>
> > (loop for n from 8 downto 0 do
> > (connect (checkbox :expand nil)
> > (lambda (widget)
> > (if (gtk-toggle-button-active widget)
> > (format t "Pressed ~s.~%" n)
> > (format t "Released ~s.~%" n))))))
> >
> > Am i missing something fundamental?
> > Thanks in advance
>
> what happens if you change to the following?
>
> (loop for n from 8 downto 0 do
> (connect (checkbox :expand nil)
> (let ((n n))
> (lambda (widget)
> (if (gtk-toggle-button-active widget)
> (format t "Pressed ~s.~%" n)
> (format t "Released ~s.~%" n)))))) )

That worked! Thank you
Why did that work btw?

Jim Newton

5/30/2016 10:28:00 PM

0

my guess is that loop destructively modifies the variable each time through the loop. The let forces a new one to be allocated. The same is probably true for DO and DOLIST

Kaz Kylheku

5/30/2016 11:50:00 PM

0

On 2016-05-30, Eduardo V. <lalohao@gmail.com> wrote:
> El lunes, 30 de mayo de 2016, 7:33:15 (UTC-5), Jim Newton escribió:
>> On Monday, May 30, 2016 at 1:11:20 PM UTC+2, Eduardo V. wrote:
>>
>> > (loop for n from 8 downto 0 do
>> > (connect (checkbox :expand nil)
>> > (lambda (widget)
>> > (if (gtk-toggle-button-active widget)
>> > (format t "Pressed ~s.~%" n)
>> > (format t "Released ~s.~%" n))))))
>> >
>> > Am i missing something fundamental?
>> > Thanks in advance
>>
>> what happens if you change to the following?
>>
>> (loop for n from 8 downto 0 do
>> (connect (checkbox :expand nil)
>> (let ((n n))
>> (lambda (widget)
>> (if (gtk-toggle-button-active widget)
>> (format t "Pressed ~s.~%" n)
>> (format t "Released ~s.~%" n)))))) )
>
> That worked! Thank you
> Why did that work btw?

You're missing that loop is iterative; it doesn't instantiate a fresh
variable n for each iteration of the loop. This means that all the
lexical closures created by lambda capture the same variable n;
they do not see different environments.

The let construct introduces a new environment around each lambda
which is extended with a fresh binding for a new variable n
(which receives its value from the outer loop variable n,
and then shadows that outer n).

Each lambda then captures this this fresh environment.

smh

6/6/2016 4:55:00 AM

0

On Monday, May 30, 2016 at 3:28:20 PM UTC-7, Jim Newton wrote:
> my guess is that loop destructively modifies the variable each time through the loop. The let forces a new one to be allocated. The same is probably true for DO and DOLIST

Use of "probably true" here is bogus. Both DOLIST and DOTIMES have explicit text in the ANS:

It is implementation-dependent whether [dolist,dotimes] establishes a new binding of var on each iteration or whether it establishes a binding for var once at the beginning and then assigns it on any subsequent iterations.

However the detailed descriptions of the initialization and update paths for DO and LOOP make clear that these macros bind each iteration variable only once and update the values of these bindings each iteration.

So that's what user code can and cannot depend upon with regard to binding semantics of these iteration macros.