Build variations from a named track while keeping the original part and its musical identity clear.
As-built compiler behavior for Language Studio Consolidation Stage 2.
A name keeps the musical value#
t = play "saw" "c3 e3 g3"
main = t |> delay 250ms 0.4 { damp = 0.3 }
main receives a copy of t's notes, timing, voice reference, controls, and existing effect chain, then adds its delay. It does not modify t. Both names remain independently playable tracks: start only main when comparing this with an inline chain. Playing both layers the dry and derived tracks.
Multiple aliases, forward declarations, local let bindings, and qualified imported track values work through the same lowering path. Declaration order does not decide which effect overload a proven track receives. A local name does not create an additional playback track. Each top-level destination keeps its own name, annotations, scene membership, and hot-swap identity.
Reusable transforms#
An explicit receiver type documents a reusable transform and selects its named options:
echo : Track -> Track = \input -> input |> delay 250ms 0.4 { damp = 0.3 }
t = play "saw" "c3 e3 g3"
main = t |> echo |> reverb 0.2
Typed transform aliases and functions returning tracks are supported. Untyped helpers specialize when the call supplies a track or a pattern: echo = \t -> t |> delay 250ms 0.4 can be used as track |> echo. Local helpers and closure factories retain their captured values. An annotation is still needed when a definition's overload-specific options cannot be checked until its receiver type is known. Compile-time if can select a track expression; a live condition cannot select whole track graphs this way. Use chooseBy for live pattern selection. Recursive track dependencies fail with a located diagnostic. Shape lookup and lowering are bounded; this is not general recursive graph evaluation.
Randomness belongs to the defining track#
Named tracks are realized once per compilation. Two consumers of a track with inline humanize reuse the same realized events, even when the source track is declared after its consumers. Looking up the source does not reset the consumer's own random occurrence counters.
Moving a randomized inline expression into a newly named declaration changes its seed under Volta's existing name-based randomness contract. That is different from reusing an already named value. For an extraction that must keep identical draws, keep the randomized pattern in the same named binding and share that pattern. Whitespace changes do not change the binding seed.
Source editing and current limits#
Inherited effects remain audible and visible, but their consumer-side source anchors and EQ-literal edit targets are omitted. Edit the original definition in Source; its local anchors remain intact. Newly written outer effects keep their own anchors. Effects produced by function, local-binding or conditional expansion are also conservatively unanchored, and imported tracks expose no entry-buffer effect edit targets. This avoids editing a shared definition accidentally or interpreting an imported byte offset as a location in the current file.
Options can be shared through forward alias chains, local or top-level record factories, projections and static choices. Known receiver and pattern unit types specialize through local aliases and returned closures; unresolved higher-order results still need an annotation. This is bounded compile-time elaboration, not general recursive graph evaluation. Whole-mix bounceOf … master semantics remain as documented in Mixing tracks and buses.