Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

1.7 Scoping

Block Scope

Variables are block-scoped. A new scope is created for:

  • Function bodies
  • If/else branches
  • Loop bodies

Variables declared in an inner scope shadow variables with the same name in outer scopes.

Name Resolution

When a bare identifier is referenced (not followed by (), it is resolved by searching:

  1. Current block scope
  2. Enclosing block scopes (innermost to outermost)
  3. Function parameters
  4. Global scope (top-level constants, globals, and functions)

Ignored type declarations participate only in type annotations and other ignored type declarations. If a name resolves to an ignored type declaration and is used as a runtime value, compilation fails.

If not found in any runtime scope, it is treated as a forward reference to a function.

Named calls (name(...)) skip this search and always resolve name as a top-level function (or intrinsic). A local or global binding does not intercept them. Binding a name that already names a top-level function is therefore ill-formed.

Global Scope

Top-level declarations are in global scope and visible throughout the file (including before their declaration point due to forward reference handling).