Acquis 13 - While-Assignment

The while statement can now include assignments in its condition. Variables assigned in the condition are scoped to the loop body, and the expression is re-evaluated on each iteration.

Syntax

Assignments use the = operator within the condition:

while var = expr do
    -- var is available here
    -- expr is re-evaluated each iteration
end

while a, b = expr1, expr2 do
    -- all variables available here
end

The condition is true when all assigned values are truthy (not nil or false). When any value becomes falsy, the loop exits.

while x = getNext() do
    print(x)  -- prints each value until getNext() returns nil
end

Single variable assignment

The simplest form assigns one value and tests it on each iteration:

local function makeCounter(max)
    local i = 0
    return function()
        i = i + 1
        return i <= max and i or nil
    end
end

local next = makeCounter(3)
while v = next() do
    print(v)  -- prints 1, 2, 3
end

This is particularly useful for iterator functions:

while line = file:read() do
    process(line)
end

Multiple variable assignment

Multiple variables can be assigned and tested simultaneously:

while a, b = getTwo() do
    print(a, b)
end

The condition fails if any assigned value becomes falsy:

local function coords()
    -- returns nil, nil when done
    local x, y = getNextPoint()
    return x, y
end

while x, y = coords() do
    plot(x, y)
end

Variable scoping

Variables declared in while conditions are scoped to the loop body:

while data = fetch() do
    process(data)
end
-- data is not visible here

This prevents pollution of the outer scope and clearly indicates the variable’s purpose.

Comparison with standard Lua

Redundant patterns

A common Lua pattern requires separate assignment and test:

-- Lua: separate assignment and test
local line = file:read()
while line do
    process(line)
    line = file:read()  -- must repeat the expression
end

With while-assignment:

-- Lus: combined
while line = file:read() do
    process(line)
end

Iterator simulation

While-assignment provides a cleaner alternative to complex iterator protocols for simple cases:

-- Lus: simple iterator pattern
local function queue_pop(q)
    return table.remove(q, 1)
end

local queue = {1, 2, 3, 4, 5}
while item = queue_pop(queue) do
    print(item)
end

Relationship to If-Assignment

While-Assignment extends Acquis 3 (If-Assignment) with the same semantics:

  • Same syntax: NAME { ',' NAME } '=' explist
  • Same truthiness test: condition fails if any value is falsy
  • Key difference: the expression is re-evaluated on each loop iteration