Skip to content

Nullability and lexical lookups #22

@mattbasta

Description

@mattbasta

Similar to #21, it's possible for functions to lexically access variables that contain an undefined value:

object TestObject {}

func main() {
    func TestObject:foo() {
        return x;
    }
    var y = foo();
    var x = new TestObject();
}
export main;

The above code should raise a compile-time exception. There are two solutions, which change the semantics of lexical accesses.

The first solution is to require all lexical lookups to be for variables that are immutable (primitives, strings) or nullable types. This will satisfy the correctness aspect of the problem, but it changes the semantics of a variable declaration to always require the implementation to hoist the variable to the top of the function it is defined in.

The second solution is to map dependencies of lexical lookups. This may be expensive, and it is unclear whether it is even entirely possible. The cost to the user is potentially cryptic error messages. In short, all nested functions will have their lexical dependencies collected. When a function is referenced (i.e., when its identifier is used as a symbol, or when a function expression or lambda is written), an assertion will be made that all of its dependencies have already been satisfied. In the above example, foo would be identified to depend on x. When foo is referenced in y's declaration, the assertion that x is defined would fail.

The second solution could be augmented to only apply to mutable types in order to minimize the amount of confusion to developers, though this would again have the downsides of the first solution (implying that immutable variables are hoisted).

Note also that the second solution would be compatible with nested function declarations anywhere inside the parent function. The following code sample would also fail:

object TestObject {}

func main() {
    var y = foo();
    var x = new TestObject();
    func TestObject:foo() {
        return x;
    }
}
export main;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions