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

Document scoping of assignment of locals in continuations #82

Open
Technologicat opened this issue Jan 25, 2022 · 2 comments
Open

Document scoping of assignment of locals in continuations #82

Technologicat opened this issue Jan 25, 2022 · 2 comments
Assignees
Labels
documentation Non-executable English, for humans
Milestone

Comments

@Technologicat
Copy link
Owner

Currently, if you assign to a local variable in a continuation, this always creates a new name local to the continuation.

If the parent function whose continuation it is has a local variable with the same name, the standard Python semantics is to update (overwrite) that name - because looking at the unexpanded user source code, we are still inside the same function.

In actuality, we of course are not. The continuation is a closure defined inside the parent function, thus causing this bug.

This is particularly insidious because in the user code, there is no hint of another scope being introduced. For least surprise, we should maintain the illusion that the standard scoping rules apply to the unexpanded source code.

To fix this, we should be able to just nonlocal any local variables of the parent function when we generate the code for the continuation closure.

For where and how to do this, see the comment in the function split_at_callcc, in unpythonic/syntax/tailtools.py.

@Technologicat Technologicat added the bug Something isn't working label Jan 25, 2022
@Technologicat Technologicat added this to the 0.15.x milestone Jan 25, 2022
@Technologicat Technologicat self-assigned this Jan 25, 2022
@Technologicat Technologicat modified the milestones: 0.15.x, 0.15.2 Jan 28, 2022
Technologicat added a commit that referenced this issue Jan 29, 2022
Maybe not worth it, after all; much simpler, and more robust, to just document
that introducing a continuation introduces a scope boundary.
@Technologicat
Copy link
Owner Author

Technologicat commented Jan 29, 2022

Turns out this is not as straightforward as initially envisioned. 2c7477c implements propagation of the scope of variable definitions from the parent scope into the continuation, recursively. But:

  • Due to how the machinery works, the continuation's parameters (assignment targets of the call_cc) must shadow the same names from the parent scope, if they happen to exist there.
  • There is no propagation from the continuation up the parent scope chain. That is, if a continuation declares a new local variable, the name won't become available to any of the parent contexts, even if those are part of the same original function (to which the continuation splitting was applied). Implementing this would require a second pass.
  • Without looking at the source code of the full module, it is not even possible to determine whether the top level of the with continuations block is inside a function or not. This has implications to call_cc invoked from the top level of the block: should the variables from the parent scope be declared nonlocal or global?

So it may be better to abandon the experiment, and just document that introducing a continuation introduces a scope boundary. This is how it has always worked up to 0.15.1, though the fact was never documented. The behavior is no worse than how, in standard Python, comprehensions and generator expressions introduce a scope boundary.

The code of the experiment itself is sufficiently nontrivial to be worth keeping as a commented-out section, with a "don't do this, it's a bad idea" (for the above reasons) warning.

@Technologicat
Copy link
Owner Author

Thought about it a while; yes, let's abandon the experiment.

Thus, we need to update the documentation, particularly the section on continuations in doc/macros.md.

There are updated examples in unpythonic.syntax.tests.test_conts. As of f772df4, see near the end of the file.

@Technologicat Technologicat added documentation Non-executable English, for humans and removed bug Something isn't working labels Jan 31, 2022
@Technologicat Technologicat changed the title Fix scoping of assignment of locals in continuations Document scoping of assignment of locals in continuations Jan 31, 2022
@Technologicat Technologicat modified the milestones: 0.15.2, 0.15.x, 0.15.4 Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Non-executable English, for humans
Projects
None yet
Development

No branches or pull requests

1 participant