Skip to content

[fork-ffi] effect: forE — PureScript/JS forE lo hi f iterates over [lo, hi) — lo inclusive, hi… #78

@Unisay

Description

@Unisay

Package: purescript-lua-effect
File: src/Effect.lua
Function: forE
Class: off-by-one Severity: high

PureScript/JS forE lo hi f iterates over [lo, hi) — lo inclusive, hi EXCLUSIVE (the Effect.purs doc comment states this explicitly, and the JS FFI uses for (var i = lo; i < hi; i++)). The Lua port uses a numeric for-loop for i = lo, hi do, whose upper bound is INCLUSIVE in Lua. This runs one extra iteration at i = hi, so f is invoked (hi - lo + 1) times instead of (hi - lo). It also breaks the empty-range contract: forE n n should run zero times but the Lua runs once at i = n. Verified under Lua 5.1: forE 0 3 calls f at i=0,1,2,3 (count 4, JS gives 3); forE 2 2 runs once (JS runs zero times).

Current (Lua):

forE = (function(lo) return function(hi) return function(f) return function() for i = lo, hi do f(i)() end end end end end)

Expected: JS: for (var i = lo; i < hi; i++) { f(i)(); } — i ranges over lo..hi-1; forE lo hi runs exactly max(0, hi - lo) times.

Proposed fix:

Use an exclusive upper bound: `for i = lo, hi - 1 do f(i)() end`. Verified under Lua 5.1: `for i = 0, 3-1` runs 3 times; `for i = 5, 5-1` runs 0 times (Lua's for skips when start > stop), matching the JS empty-range behaviour.

Found by the FFI audit; reproduced under Lua 5.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions