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

Translate continuation into a closure that actually captures the scope #23

Open
mailund opened this issue Mar 17, 2018 · 0 comments
Open
Labels
enhancement New feature or request
Milestone

Comments

@mailund
Copy link
Owner

mailund commented Mar 17, 2018

If we create closures inside a function we transform, then the enclosing environment sees the modified local variables in the loop. This breaks the illusion that we have recursive calls.

With a function like this:

library(pmatch)
tree := L(v) | T(left : tree, right : tree)
t <- T(L(1), T(L(2), L(3)))
sum_leaves <- function(t, cont = identity) {
    cases(
        t,
        L(v) -> cont(v),
        T(left,right) -> {
            call_right <- function(left_sum) {
                  sum_leaves(
                      right,
                      function(right_sum) left_sum + right_sum
                  )
            }
            sum_leaves(left, call_right)
        }
    )
}
sum_leaves(t)

we have two closures, the named call_right and the anonymous function(right_sum) ... inside it. These will capture the environment of the sum_leaves function that contains cont. If we transform the function, however, they will have access to an updated left, right and cont and nothing good will come of that.

We can fix it by capturing cont explicitly in a closure or a thunk. In the code below, I use closures.

make_call_right_closure <- function(cont, left, right) {
    force(cont)
    force(left)
    force(right)
    function(left_sum) 
        sum_leaves(right, function(right_sum) left_sum + right_sum)
}
sum_leaves <- function(t, cont = identity) {
    cases(
        t,
        L(v) -> cont(v),
        T(left,right) -> {
            call_right <- make_call_right_closure(cont, left, right)
            sum_leaves(left, call_right)
        }
    )
}

With a bit of static analysis, we should be able to automatically extract closures and capture the right environment.

@mailund mailund added the enhancement New feature or request label Mar 17, 2018
@mailund mailund added this to To do in Thunks and trampolines via automation Mar 17, 2018
@mailund mailund added this to the 0.2.0 milestone Mar 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

No branches or pull requests

1 participant