Functions should properly close over bindings #16

Closed
opened 2024-12-09 23:04:16 +00:00 by scott · 5 comments
Owner

Currently, this gives a panic, unbound name foo.

let baz = {
  let foo = :foo
  fn bar () -> foo
}
baz ()

Should output :foo. Currently, I'm pretty sure this is because functions aren't capturing their context properly when evaluating the fn ast node (and not when they're actually run).

Currently, this gives a panic, `unbound name foo`. ``` let baz = { let foo = :foo fn bar () -> foo } baz () ``` Should output `:foo`. Currently, I'm pretty sure this is because functions aren't capturing their context properly when evaluating the `fn` ast node (and not when they're actually run).
scott added the
feature
core
labels 2024-12-09 23:04:26 +00:00
Author
Owner

This is what's causing the unbound name base errors now that I'm working on importing Prelude in #13 (comment).

The proper way to do this is to do a validation/compile pass, and in that, enumerate the bindings the function closes over, and then, instead of cloning the whole locals stack, create a new locals stack that only includes those bindings that are closed over.

That will also mean that a function actually should own a context? The lifetimes are going to be wild there, but let's give it a shot.

(That also means that, thankfully, generating stack traces should be pretty straightforward?)

This is what's causing the `unbound name base` errors now that I'm working on importing Prelude in https://alea.ludus.dev/scott/rudus/issues/13#issuecomment-1891. The proper way to do this is to do a validation/compile pass, and in that, enumerate the bindings the function closes over, and then, instead of cloning the whole locals stack, create a new locals stack that only includes those bindings that are closed over. That will also mean that a function actually should own a context? The lifetimes are going to be wild there, but let's give it a shot. (That also means that, thankfully, generating stack traces should be pretty straightforward?)
Author
Owner

With the work I've done today, circa 35e9d0373d, we have the validator properly identifying the values a function closes over, stuffing them into a hash table with the pointer to the Ast node as the key, and a HashSet containing the bindings that are closed over.

What's left to do is to rework the Fn branch of context::Context::eval to become its own Context-like thing that can be .evaled.

With the work I've done today, circa https://alea.ludus.dev/scott/rudus/commit/35e9d0373d7121b31cc3b8ab1f1c73b4cf4a61e3, we have the validator properly identifying the values a function closes over, stuffing them into a hash table with the pointer to the Ast node as the key, and a HashSet containing the bindings that are closed over. What's left to do is to rework the `Fn` branch of `context::Context::eval` to become its own `Context`-like thing that can be `.eval`ed.
scott added a new dependency 2024-12-11 05:32:22 +00:00
scott added this to the Minimal replacement for Janet-based Ludus milestone 2024-12-11 05:36:14 +00:00
Author
Owner

This is working fine in a Ludus script, as of 6a01089973. Pulling from a simplified Prelude also works.

There's some weirdness, though, in Prelude. I don't think this is done until #13 is fully accomplished.

This is working fine in a Ludus script, as of https://alea.ludus.dev/scott/rudus/commit/6a0108997368c5949b06ee089c418888699c0bfd. Pulling from a simplified Prelude also works. There's some weirdness, though, in Prelude. I don't think this is done until #13 is fully accomplished.
Author
Owner

Forward declarations were not working. They are now, with 273267f61d. The long and short of it is that we need to update closed-over bindings after the function is defined.

Still: testing required.

Forward declarations were not working. They are now, with https://alea.ludus.dev/scott/rudus/commit/273267f61d8ddcdae9f3e331f0db172a5be14e9c. The long and short of it is that we need to update closed-over bindings after the function is defined. Still: testing required.
Author
Owner

Looks like it works now! Same commit as before to have gotten them right.

Looks like it works now! Same commit as before to have gotten them right.
scott closed this issue 2024-12-13 00:40:10 +00:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Reference: scott/rudus#16
No description provided.