Skip to content


Scoping rules in NPL are similar to many other languages.

Global scope

Global scope is not available in NPL.

File scope

File scope is the scope for any top-level construct. This includes constants, functions, and protocols.

Block scope

NPL uses block-structure like constructs like functions, protocols, permissions, obligations, for loops and blocks. Each of these structures defines their own scope.

This means that defining another x within the block is legal, but its definition is not used for anything.

function blockScope() returns Number -> {
    var x = 10;
        var x = 20;
    return x;

which returns


Nesting these constructs means the nested construct has access to its outer scope. These rules also apply to functions and actions (permission or obligation) on protocols. This implies that functions on protocols have access to the surrounding protocol.

const n = 42;

function outerScope() returns Number -> {
    return n; // accesses its outer scope

Function scope

Function arguments are automatic variables. They are valid only for the duration of the function, and are destroyed at the end of the function. Function arguments are lexically scoped variables, meaning that in the following snippet each n is completely unrelated, and changes to n in square do not affect n in trimmedSquare.

function square(n: Number) returns Number -> {
    return n * n;

function trimmedSquare(n: Number) returns Number -> {
    var r = square(n);
    return if (r > 15) r else 0;