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

Safely mutating stack #47

Open
homonoidian opened this issue Oct 27, 2022 · 0 comments
Open

Safely mutating stack #47

homonoidian opened this issue Oct 27, 2022 · 0 comments
Assignees
Labels
improvement Similar to enhancement, but there is already code which addresses this that must be improved

Comments

@homonoidian
Copy link
Collaborator

The problem with stack is that most mutating or iterating words don't take its highly dynamic nature into account (to name a few: |slideRight and friends, sum, join, etc.) Same thing with conts, which also is highly dynamic (even more than stack), but use of conts is discouraged, and if you really do need to touch it, then you can shallowCopy and resub it yourself.

But being able to inspect and change stack as if it was just a block is one of the "killer features" of Novika. Expressions like 1 2 3 stack sum arise naturally.

Note that I did make some patches to reduce so it supports stack (making things like 1 2 3 stack sum leave 6 as expected), but they explicitly allowed stack, while we want to do that implicitly and relieve the burden of thinking about a weird use case like this.

For example. |slideRight doesn't assume it's running in the same stack that it's iterating over, leading to undefined behavior: 1 2 3 stack ||-> [ 1 + ] dies weirdly instead of making the stack look like 2 3 4, as one would assume.

To close this safety hole, we'd have to use some sort of instantiation or automatic split-join mechanism for stacks.

What I mean is that each stackless open (e.g. ... [ 1 + ] open as well as [ 1 + ] @: foo ... foo, i.e., opens) must make a snapshot of the stack it's being opened in, and use that stack. After it has been opened we must merge (join) its stack with the parent stack.

The only difficulty here is actually finding the parent stack (i.e. preserving parent-child relationships for stacks). We can't simply join into the upper stack because of cases like this: [ 1 2 ] [ + ] there. Here, no merge must occur. A possible solution is newing the stack in hydrate (of which there is a descendant), and making the stack instance an orphan. In case of open and friends, we also new the current stack, but this time the instance doesn't get orphan'd and thus gets a merge from the main loop, when the continuation is popped off.

As a consequence, stackless opens become atomic (and hydrates already are), meaning there is only two states: one before computation, and one after. Currently, in-between states are also accessible.

Some minor thoughts:

  • Would (probably heavily) affect performance, slowing down the interpreter even more. Doesn't matter right now though, it's slow already.
  • conts ... shove and derived expressions basically mean "f*ck off" to this whole mechanism.
  • stack still leaves legit current stack, not copy
  • [ 1 2 3 ] ||-> [ 1 + ] leaves [ 2 3 4 ], thus 1 2 3 stack ||-> [ 1 + ] should leave 2 3 4 ⭮, allowing for chains like 1 2 3 stack ||-> [ 1 + ] map: [ 2 * ]. The latter leaves 2 3 4 ⭮. and its contents, 2 3 4, are picked up by map:, leaving just [ 4 6 8 ] on the stack (as [ 1 2 3 ] ||-> [ 1 + ] map: [ 2 * ] already does.
@homonoidian homonoidian added this to the Novika 0.0.5 milestone Oct 27, 2022
@homonoidian homonoidian self-assigned this Oct 27, 2022
@homonoidian homonoidian added the improvement Similar to enhancement, but there is already code which addresses this that must be improved label Oct 27, 2022
@homonoidian homonoidian removed this from the 0.0.5 milestone Nov 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Similar to enhancement, but there is already code which addresses this that must be improved
Projects
None yet
Development

No branches or pull requests

1 participant