New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables in nested closures #864

Closed
emilwestergren opened this Issue Feb 17, 2015 · 4 comments

Comments

Projects
None yet
3 participants
@emilwestergren

emilwestergren commented Feb 17, 2015

Should it be possible to create a closure inside another closure? Because it is in that case not possible to use variables created in the parent closure in the child closure.

Example code:

func1 := func {
    a := 1
    b := 2
    func2 := func { println((a + b) toString()) }
    func2()
}
func1()

fails with:

NestedClosureTest.ooc: In function ‘test_sdk_NestedClosureTest_load’:
NestedClosureTest.ooc:3:13: error: ‘a’ undeclared (first use in this function)
  a := 1
             ^
NestedClosureTest.ooc:3:13: note: each undeclared identifier is reported only once for each function it appears in
NestedClosureTest.ooc:4:13: error: ‘b’ undeclared (first use in this function)
  b := 2
             ^
NestedClosureTest.ooc: In function ‘test_sdk_NestedClosureTest____test_sdk_NestedClosureTest_test_sdk_NestedClosureTest_closure4’:
NestedClosureTest.ooc:3:23: error: ‘a’ redeclared as different kind of symbol
  a := 1
                       ^
NestedClosureTest.ooc:8:117: note: previous definition of ‘a’ was here
 func1()
                                                                                                                     ^
NestedClosureTest.ooc:4:23: error: ‘b’ redeclared as different kind of symbol
  b := 2
                       ^
NestedClosureTest.ooc:8:138: note: previous definition of ‘b’ was here
 func1()
@zhaihj

This comment has been minimized.

Contributor

zhaihj commented Feb 17, 2015

Things messed up when variable appears.
line no.104,105 cause this problem. Here we are generating unnecessary context __vvv_ctx5.

101         __vvv_ctx5 = lang_Memory__gc_malloc(((lang_types__Class*)__vvv_vvv_closure4_ctx_class())->size);
102         #line 1 "/home/housezet/.ooc_libs/mcs/test/rock/vvv.ooc"
103         (*(__vvv_ctx5)) = (__vvv_vvv_closure4_ctx) {
104             a,
105             b
106         };
107         __vvv_closure6 = (lang_types__Closure) {
108             vvv____vvv_vvv_closure4_thunk,
109             __vvv_ctx5
110         };
@zhaihj

This comment has been minimized.

Contributor

zhaihj commented Feb 17, 2015

It seems to be a bug in VariableDecl -> captureInUpstreamClosures -> intermediateScopeIndex
W should also check if var is defined in parent closure.

zhaihj added a commit to zhaihj/rock that referenced this issue Feb 17, 2015

@zhaihj

This comment has been minimized.

Contributor

zhaihj commented Feb 20, 2015

A related problem(UNRESOLVED):

main: func{
    ret := 1
    1 times(|| 2 times(|| ret += 1))
    ret toString() println()
}

Expect: 3
Got: 1

because rock generate &(&ret) in nested closure...

@fasterthanlime

This comment has been minimized.

Collaborator

fasterthanlime commented Jul 7, 2015

My example (for the original issue, not #882)

func1 := func {
    a := 1
    b := 2
    func2 := func {
        "#{a + b}" println()
    }
    func2()
}
func1()

Note that if you change func1 := to func1: it doesn't happen. Looks like isDefined doesn't do the right thing..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment