A reddit discussion led me to write down some ideas I’d been considering for scopes in Plasma.
Plasma is a single-assignment language and has some unusual rules for variable scoping, if all paths assign a variable, then it is available in all following scopes (until the end of the function). This allows you to do things like.
if (...) { # complex computation over many lines x = ... } else { x = ... y = ... } i_can_use(x) # I can't use y, it is only available in the else branch.
But because it’s single assignment, and people may want fresh variables, We’re considering adding something that can scope variables more traditionally.
scope { x = ... i_can_use(x) } # x is out of scope.
Michael Richter suggested an extra feature we could add here, which we’re considering. The same scope could be used to hide a variable so you can have a fresh one in a local scope, this could be useful since it’s a single assignment language.
y = 1 scope hide (y) { # y is not in scope. y = "quax" # y is now "quax", it's totally different from # the y above, as if it had a different name, # so of course it can have a different type # and value. } # The original y is back in scope, it is 1.
One thing is missing, if we want some variables to be available after this block (like if-then-else) but still want x to have that smaller scope, we’d need to list either the ones that get the smaller scope or those that get exported. So we could add more syntax for that.
scope (x) hiding (y) { ... }
What do you think? We definitely want to keep Plasma as a single assignment language, and probably add a special syntax for accumulators/state. Experience with Mercury tells us that this is a good way to program, and not the burden it initially seems.
-
2017-07-22 Add a correction, it’s possible (and better) to list the exported variables.