explanationView source

Application and composition

(f a b) applies f to a, then applies the result to b. The explicit (app f a b) spelling remains accepted. A function may return another function; the checker follows its type instead of counting syntactic lambda binders.

Import Std.Function for pure, unrestricted composition:

stdCompose A B C outer inner value = outer (inner value)
stdPipe A B C firstFunction secondFunction value = secondFunction (firstFunction value)

The three types are explicit erased arguments. The input value is last. If increment x = x + 1 and double x = x + x, composing increment after double at 1 produces 3; piping through increment then double produces 4.

These helpers do not sequence effects themselves. Functions that accept File computations must use checked bind to establish order. The native fixture EffectOrder.alpha appends A then B through two such functions; its Alpha test observes exactly AB. Swapping those functions produces BA and fails the test. These unrestricted helpers do not grant permission to duplicate a linear value.

Use alpha fmt FILE --stdout for canonical spelling and alpha fmt FILE --expanded --stdout or alpha inspect FILE --expanded for explicit application. The formatter keeps app where removing it would change the parse, including (app first p): (first p) means pair projection. Computed function heads also retain app where required by the grammar. Comments and literals are preserved.

The edition migration registers app-to-bare-application. It checks the complete source and rewritten closure under the target edition before writing; invalid over-application is refused. alpha migrate --from alpha-2026 --to alpha-2027 --check previews all registered boundary rules, including numeric and byte literal rewrites. Migration does not itself change the project's edition field.