Skip to content

Generic fallback: flatten deeply-nested do-blocks for non-Effect/ST monads #104

@Unisay

Description

@Unisay

Split off from #46.

#46 fixes the Lua parser nesting limit (chunk has too many syntax levels, LUAI_MAXCCALLS ≈ 200) for the common case by adding magic-do for Effect and ST: their bind/discard/pure chains compile to a flat statement sequence instead of nested continuations.

That leaves the general case: a long straight-line do/>>= chain in any other monad (Maybe, Either, Aff, State, Writer, a custom parser/decoder, or a large applicative ado) still emits ~200+ lexically nested closures and hits the same parser limit.

Why this matters specifically for the Lua backend

On the JS/ES backends deep nesting is only a performance cost — their parsers have no comparable cap. On Lua it is a correctness failure: the file will not even load. So, unlike upstream, we eventually need a backend-agnostic nesting breaker, not just Effect/ST magic-do.

Why it is harder than magic-do

magic-do works because Effect is \() -> ... (a thunk we can inline as local x = m()). For a general monad, bind m k is a real call with monad-specific semantics — it cannot be turned into a sequential local. The naive "hoist continuations into named locals" does not work either: a x <- m continuation captures x, and a later action may reference earlier xs, so the continuation cannot leave the enclosing scope.

A real fix needs one of:

  • a CPS / trampoline-style transform, or
  • chunking the chain into helper functions that thread the live environment as explicit parameters, breaking the chain into segments each below the nesting cap.

Realistic triggers

Uncommon in hand-written code; realistic in machine-generated code, decoders/validators for very wide records, and large ado constructors (and Aff, if/when it is ported to Lua). Lower priority than #46 accordingly.

Acceptance

A do block of N ≫ 200 statements in a non-Effect monad (e.g. a long Maybe/State chain) compiles to Lua that loads and runs correctly under stock Lua 5.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: codegenLua code generation / printingenhancementNew feature or request

    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