Skip to content
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
Closed

Variables in nested closures #864

emilwestergren opened this issue Feb 17, 2015 · 4 comments
Milestone

Comments

@emilwestergren
Copy link

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()
@horasal
Copy link
Contributor

horasal 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         };

@horasal
Copy link
Contributor

horasal 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.

horasal added a commit to horasal/rock that referenced this issue Feb 17, 2015
@horasal
Copy link
Contributor

horasal 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
Copy link
Collaborator

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants