Standard library
mu keeps the host builtin surface small and grows capability through mu-written modules.
Three layers
- Host builtins (Go)
- A fixed set of 27, like
len,append,error,type,inspect,syscall,buf, anddlcall. Runhelp()for the full list. - A capability earns a place here only when mu genuinely cannot express it — it needs the kernel, raw memory, the loader, the scheduler, the runtime type tag, or a mutation mu has no other way to perform. Every one of them is implemented four times over (Go interpreter, Go native, self-hosted interpreter, self-hosted native), so the table is kept deliberately small.
- A fixed set of 27, like
- µ-builtins helpers (mu)
- Ambient globals from
lib/builtins.mu, likeprint,panic,test, andexit— plusinput,bool,values,has,int,insert,is_error,mustandtry. They are ordinary closures or macros written in mu:type(bool)is"CLOSURE".
- Ambient globals from
- Namespaced modules (mu)
- Import explicitly and call helpers behind a namespace, e.g.
strings.split. - The µ-builtins module is ambient, not importable: use
has(m, k)directly;import "builtins"is refused.
- Import explicitly and call helpers behind a namespace, e.g.
Key modules
io: file paths, descriptors, complete writes, read/write/open/close, stdin line input, and the platform details underneath themstrings: split/join/trim/replace and string utilitiestime: clocks and sleep helpersassert: assertions for tests and scriptsfp: functional utilities like map/filter/reduceiter: the lazy counterpart tofp— the same vocabulary over producers instead of listsdecimal: exact fixed-point arithmetic — what3.14is built fromshape: tagged-map constructors and validators for recurring data contractsmacroandcode: define macros, and take code values apartjson: deterministic encoding and strict decoding to mu values, including exactDecimalvalues for fractional numberspath,process,sqlite,sockets,text, and more
help(name) prints a module’s documentation and its exports, so
import "decimal" then help(decimal) is usually faster than reading source.
Public surface
Documented non-underscore names are the stable module API. Names beginning with
_ are implementation helpers, even when they live in an importable helper
module. The language does not enforce private module members yet, so the stdlib
uses this convention to keep source and help() output honest.
Shapes and protocols
Plain functions are the default. When a recurring map shape or behavior contract appears, define a constructor or protocol-shaped helper instead of adding language syntax.
shape.new(type_name, fields, methods?) creates a tagged map whose __type
field makes type(value) report the domain name. result.Result uses this
pattern today; richer values such as Decimal also carry behavior through
methods and __ops.
Example
import "strings"
line := " hello,mu "
trimmed := strings.trim(line)
print(trimmed)
Lazy iterators
iter builds pull-driven iterators on tasks and channels. Values are produced
on demand, so a chain over an endless source only does the work the consumer
asks for:
import "iter"
naturals := iter.iterate(1, fn(n) { return n + 1 })
squares := iter.map(naturals, fn(n) { return n * n })
print(iter.collect(iter.take(squares, 5))) // [1, 4, 9, 16, 25]
Iterators are written with two macros the module exports — foreach to pull a
source until it is dry, and emit to publish a value and return if the consumer
has cancelled:
fn evens(source) {
return iter.iterator(fn(yield) {
iter.foreach(value, source, fn() {
if value % 2 == 0 {
iter.emit(yield, value)
}
})
return nil
}, source)
}
They are macros rather than functions because both return on behalf of the
function that called them — see macros for why that cannot be a
call, and what foreach gives you that a callback cannot.
A consumer that stops early should say so, with iter.stop(source): it cascades
to everything upstream, so an abandoned producer is not left parked.
Guidelines
The stdlib stays small, composable, and explicit. New helpers should return errors as values, avoid hidden global state, and avoid compatibility aliases when one canonical name is clear.
See docs/StdlibGuidelines.md for the detailed conventions.
Next steps
- Start with the language tour if you’re new.
- Learn how the VM and native backend work in the runtime guide.
- Explore macros in macros for compile-time helpers.