-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Currently, this type of code that replicates oscillator with recursive function, works.
fn osc(freq,rate){
...
}
fn replicate(n,gen:()->(float,float)->float){
if (n>0.0){
let c = replicate(n - 1.0,gen)
let g = gen()
|x,rate| g(x,rate) + c(x+100.0,rate+0.1)
}else{
|x,rate| 0
}
}
let mycounter = replicate(20,| | osc);However, this code does not work.
fn osc(freq,rate){
...
}
fn replicate(n,gen:(float,float)->float){
if (n>0.0){
let c = replicate(n - 1.0,gen)
|x,rate| gen(x,rate) + c(x+100.0,rate+0.1)
}else{
|x,rate| 0
}
}
let mycounter = replicate(20, osc);This is because the closure is heap-allocated and the real value on the stack is the pointer to the closure.
When the instantiated closure is passed as an argument, the closure is "shallow" copied and its statestorage are shared between cloned instances. I was wondering which spec was correct for a while, but now I think "deep" copy is the right choice for this case.
I'm not sure if there are really no problems around upvalue treatise, but it works if my guess is right.
To implement this, add something like "CloneClosure" instruction to the MIR and bytecode, is the straightforward way.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working