Pyro

A dynamically-typed, garbage-collected scripting language.

Version 0.19.2

Loop Closures


Pyro has three different kinds of loops — closing over the loop variable behaves differently in each case.

C-Style Loops

A C-style loop has a single loop variable that's shared by every iteration of the loop, e.g.

var closures = [];

loop var i = 0; i < 3; i += 1 {
    closures:append(def() {
        return i;
    });
}

assert closures[0]() == 3;
assert closures[1]() == 3;
assert closures[2]() == 3;

Each closure is capturing the same i variable.

For-In Loops

Each iteration of a for-in loop has its own independent loop variable that can be independently captured, e.g.

var closures = [];

for i in $range(3) {
    closures:append(def() {
        return i;
    });
}

assert closures[0]() == 0;
assert closures[1]() == 1;
assert closures[2]() == 2;

Each closure is capturing a different i variable.

While Loops

while loops don't support variable declarations, so there's no scope for ambiguity, e.g.

var closures = [];
var i = 0;

while i < 3 {
    closures:append(def() {
        return i;
    });
    i += 1;
}

assert closures[0]() == 3;
assert closures[1]() == 3;
assert closures[2]() == 3;

Each closure is capturing the same i variable.

Rationale

This distinction sounds complicated when stated explicitly but in practice it should be intuitive. It's designed to conform with programmers' intuitions of how loop-variables should behave.