Lyric
A statically typed application language with a bytecode VM — standalone, and embeddable in a host with a capability-based sandbox.
What changed in v1.15.0 — 2026-08-19
The freeze prep: the design leftovers settled before the spec freezes semantics. opaque type
arrives, the string API becomes methods, iterator chaining gets its documented No — and a
latent function-id collision in the lowering falls. The bytecode format stays 3.2.
Fixed
- A function-id collision in the lowering, latent since struct-returning natives: the global initializer's slot was reserved only for DECLARED globals, but a struct-return buffer CREATES one during body lowering — and once a body also requested an extension method (the new string methods do), initializer and extension landed on the same id, and calls mis-spliced into the wrong function. The initializer draws from the shared id counter now, and the function list refuses id holes with a named internal error instead of a silent mis-splice.
Added
Strings have methods:
s.trim(),s.split(","),s.contains(x),s.length()— 26 methods viaextend stringinstd.string. The free forms warn as deprecated and go with 2.0;concatandrepeatstay free (they back+and*), and the type-directed families (fromXxx,parseXxx) keep their names. The methods come with any import of the module; a file needing no free name writesimport std.string as strings;— and an import whose extensions are used no longer counts as unused.s.length()stays a call because it costs O(n), and every method returns a NEW string.opaque type: an alias with a new IDENTITY over the same layout —pub opaque type Entity = int;. Nothing converts implicitly in either direction; the explicitasto exactly the underlying and back is the one crossing;==/!=compare within one alias; arithmetic, ordering, constraint satisfaction and f-string rendering are refused. At runtime the value IS its underlying (the cast costs nothing), and a native signature resolves the alias to the underlying — an SDK's handle crosses the host boundary as a plain number while scripts can neither forge one nor leak it. Neitheropaquenortypeis a keyword; both stay usable as identifiers.