Skip to content

stdlib has never been AOT-compiled as a coherent unit (angle-applied types + flat-namespace collisions; string.affine is the first symptom) #128

@hyperpolymath

Description

@hyperpolymath

Summary

The AffineScript stdlib has never been compiled through the static
resolve → typecheck → codegen pipeline as a coherent unit.
It is
interpreter-era code (dynamically typed, flat global namespace) that the
AOT path has never exercised end-to-end. stdlib/string.affine is the
first file that surfaced this (originally reported here), but the two
root causes are stdlib-wide, not string-specific.

This issue is rescoped from "stdlib/string.affine does not compile" to
the actual underlying defect.

Reproduce (original symptom)

affinescript compile stdlib/string.affine -o /tmp/x.deno.js --deno-esm
# => affinescript: Resolution error  (fails at resolve, before typecheck/codegen)

Root causes (both stdlib-wide)

1. Angle-bracket applied types are the stdlib's surface, not a string.affine quirk

The static front-end accepts <...> for type parameters but
rejects it for applied types in value/return position
(fn char_at(...) -> Option<Char>). That asymmetry is the actual
defect. It is pervasive, not local:

file <…> usages
option.affine 36
result.affine 24
collections.affine 22
testing.affine 18
prelude.affine 15
io.affine 10
string.affine 5

Rewriting only string.affine to bracket form yields a file that still
cannot use option.affine / prelude.affine because those don't
resolve either — a single-file smoke check would pass while the stdlib
remains incoherent.

2. No module/import story; flat-namespace collisions

No stdlib file uses use / import / open. prelude.affine and
option.affine both define is_some / is_none / unwrap /
unwrap_or / map / filter / contains, with conflicting
signatures
(prelude.map(arr, f) vs option.map(f, opt)). Commit
b895374 ("seed Some/None/Ok/Err builtins so it resolves standalone")
is a band-aid that entrenches the interpreter-era global namespace
rather than resolving it; the original "add prelude/option imports or
qualify Option::Some" suggestion assumes import machinery the stdlib
has never been run through under AOT.

Decision required (resolve at source)

Pick the applied-type surface once and apply it uniformly. Per-file
rewrites are the worst of both options.

  • (Preferred) Accept Option<Char> in applied position in the
    resolver.
    Cheap, consistent with the <...> parameter syntax
    already accepted, makes the entire existing stdlib compile
    unchanged.
  • Bracket-only. Migrate all of stdlib/*.affine + docs + examples
    in one sweep and remove the angle alias so it cannot rot back.

Scope of work

  1. Decide + implement the applied-type surface uniformly (above).
  2. Resolve the duplicate-definition / namespace question: does the
    stdlib have modules, or stay flat-and-deduplicated? Remove the
    conflicting prelude vs option overlaps either way.
  3. Add a stdlib-wide AOT compile-smoke gate: every
    stdlib/*.affine through resolve → typecheck → codegen, plus at
    least one test that uses several stdlib modules together, so the
    AOT path can't silently rot again. (Not a single-file check.)

Impact / scope

Non-blocking and separate from #122. The Deno-ESM consumer migration
(ubicity#30 → ubicity#31/#33) deliberately does not depend on the stdlib
(self-contained extern fn primitives; ubicity green 44/44). This is
the separately-tracked structural loose end noted during the #122 work,
now scoped to its true root cause.

Refs #122, #123, #125, #127. Supersedes the original
string.affine-only framing of this issue.


Tracking (sub-issues)

This issue is now the tracking epic. Work items, with dependencies:

Suggested order: #131#132#133#135#136#137#138, with #134 doable anytime in parallel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmajorMajor issue — significant scope, broader impact than a feature/bug

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions