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 hoisting semantics #62

Open
mkhan45 opened this issue Nov 2, 2021 · 1 comment
Open

Document hoisting semantics #62

mkhan45 opened this issue Nov 2, 2021 · 1 comment
Assignees
Labels
documentation Needed documentation or quide question Question asking for help or clarification

Comments

@mkhan45
Copy link

mkhan45 commented Nov 2, 2021

Right now, this example prints 106:

z = 3
f = x -> x + y + z
y = 5
z = 100

println (f 1)  --  106

z is marked as resolved and f captures its reference, so it later evaluates to 100 when f is called. y is properly hoisted such that it evaluates to 5 in the closure.

Instead, this should be a compile time failure since z is marked as immutable by f's capture.

Discord thread: https://discordapp.com/channels/651996477333438474/730624907607539722/904815689154564227

@slightknack slightknack self-assigned this Nov 3, 2021
@slightknack
Copy link
Member

Thanks for taking the time to put this in! Aside from hoisting, we need to document the semantics of mutability and immutability in Passerine, especially the concept of 'local mutability.' Maybe now would be a good time to start building out the Codex?

Here's a brief rundown of what should happen:

  1. Variables are mutable in the scope in which they are defined, i.e. while on the stack.
    -- this is valid
    x = 5
    x = 4
  2. Function calls are pass-by-value. Mutating a function parameter makes a copy[^1] and does not effect the original value:
    f = x -> { x = 2; x }
    y = 7
    f y -- is 2
    y -- is 7
  3. Closures are capture-by-value. Mutating a captured value (inside or outside the closure) is a compile-time error:
    -- compile-time error:
    x = 7
    f = () -> { x = 2; x }
    -- also:
    x = 7
    f = () -> x
    x = 2
  4. Variables may be shadowed:
    x = 7
    f = x -> { x = 2; x } -- shadowed
    f 7 -- is 2
    x -- is 7

This is just a brief overview, I think we should provide more examples in the documentation. I'd like to include a method for closures to capture by reference in trivial cases, i.e. closures that do not escape the scope in which they are defined. I'd also like a way to introduce variables guaranteed to be immutable, through something like let x = ....

[1]: Pass-by-value does not always cause an actual copy to occur because of FBiP due to Vaporization. In the case of last-use, the original value is passed and may be mutated:

mutate_first = list -> { list[0] = 0; list }

big_list = [ ... ]
big_list = mutate_first big_list -- last use of big_list
print big_list -- no copies have been made

@slightknack slightknack added question Question asking for help or clarification documentation Needed documentation or quide labels Apr 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Needed documentation or quide question Question asking for help or clarification
Projects
None yet
Development

No branches or pull requests

2 participants