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

Scope

Global Scope

Variables can be defined in global scope, which makes them available to all other expressions in the language. This is commonly used to define certain operational constants that will be used repeatedly. See Global Values for more information on what is allowed in global scope.

let MAX_RETRIES = 3

function retry_thing() bool {
    let state = unwrap_check query State[]=>{retries: ?}
    return state.retries > MAX_RETRIES
}

Blocks

Named values are scoped to blocks. A block is usually anything enclosed in curly brackets that contains statements – a function, an action, a command policy block, an if statement block, a block expression, etc.

let in an enclosing block is scoped to that block. Using such a definition outside of that block will cause a compile error.

action foo(x int) {
    if x == 1 {
        let y = 4
        publish Foo { y: y }
    }
    // This is an error - y does not exist in the outer scope
    publish Foo { y: y }
}

Resolving an identifier traverses upwards through enclosing scopes. The global scope is the last scope in this search and is always present.

let assignments cannot assign to any names already resolvable in the current scope. Shadowing an existing identifier this way is a compile error.

action foo() {
    let x = 1
    if x == 1 {
        // This is an error - x is already defined
        let x = 4
    }
}