❌ [a108] Lambda expression unable to capture a for-loop's variables

Report problems with documented functionality
User avatar
lvalkov
Posts: 56
Joined: 08 Mar 2019, 16:39

❌ [a108] Lambda expression unable to capture a for-loop's variables

07 Dec 2019, 18:47

Not a bug as per:
lexikos wrote:
07 Dec 2019, 19:02
Variables are captured by reference...

Given an Array A, for each element, store a capturing lambda in Array B. Later, invoke them, yielding the following erroneous results:

Code: Select all

A := [1, 2, 3]
B := []

for item in A
	B.Push(() => MsgBox(item))

%B[1]%() ; MsgBox(''), expected MsgBox('1')
%B[2]%() ; MsgBox(''), expected MsgBox('2')
%B[3]%() ; MsgBox(''), expected MsgBox('3')

Introducing a temp variable yields the following:

Code: Select all

A := [1, 2, 3]
B := []

for item in A
{
	temp := item
	B.Push(() => MsgBox(temp))
}

%B[1]%() ; MsgBox('3'), expected MsgBox('1')
%B[2]%() ; MsgBox('3'), expected MsgBox('2')
%B[3]%() ; MsgBox('3'), expected MsgBox('3')

Reverting back to Func/Bind resolves the issue:

Code: Select all

A := [1, 2, 3]
B := []

for item in A
	B.Push(Func('MsgBox').Bind(item))

%B[1]%() ; MsgBox('1'), expected MsgBox('1')
%B[2]%() ; MsgBox('2'), expected MsgBox('2')
%B[3]%() ; MsgBox('3'), expected MsgBox('3')
Last edited by lvalkov on 08 Dec 2019, 09:49, edited 1 time in total.
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: [a108] Lambda expression unable to capture a for-loop's variables

07 Dec 2019, 19:02

Variables are captured by reference, not by value. There is only one variable named item, not one for each iteration.

This is a common mistake in Javascript. One small difference here is that when our for-loop completes, it restores the variable to the value it had prior to the loop (nothing), so you get nothing instead of the very last item.
User avatar
lvalkov
Posts: 56
Joined: 08 Mar 2019, 16:39

Re: [a108] Lambda expression unable to capture a for-loop's variables

08 Dec 2019, 09:44

Okay, I will work around this using Func/Bind or nested function wrappers.
joefiesta
Posts: 383
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: ❌ [a108] Lambda expression unable to capture a for-loop's variables

09 Dec 2019, 11:18

@Ivalkov : It would be nice if you posted code that actually executes.
User avatar
lvalkov
Posts: 56
Joined: 08 Mar 2019, 16:39

Re: ❌ [a108] Lambda expression unable to capture a for-loop's variables

10 Dec 2019, 00:34

@joefiesta
Each of the code samples, submitted thus far, can be run in isolation and is guaranteed to, at the very least, 'execute' on the version targeted by this bug report.
I have settled on resolving my issue using Func/Bind. If you are looking for an example of that, look no further than code sample #3 in my original post.

If you are looking for an example using nested function wrappers:

Code: Select all

f() {
	A := [1, 2, 3]
	B := []

	g(x) => B.Push(() => MsgBox(x))

	for item in A
		g(item)

	return B
}

B := f()
%B[1]%() ; MsgBox('1'), expected MsgBox('1')
%B[2]%() ; MsgBox('2'), expected MsgBox('2')
%B[3]%() ; MsgBox('3'), expected MsgBox('3')

Return to “Bug Reports”

Who is online

Users browsing this forum: Xtra and 5 guests