Four #-prefixed names are reserved for the language's own namespaces. #builtin.<function>, for example, reaches a builtin free function even when your own code shadows its name. #builtin is also every builtin type's full name: Number is #builtin.Number. The embedded-language macros - #SQL, #HTML, #VUE, ... - take a {{{ ... }}} body written in another language, and the string macros - #format"..." - take a string. You can write your own of either kind, and derive and attribute macros too, and query the whole program for definitions carrying an attribute.
Everything the language ships with rather than being written in it.
#builtin-operatorsThe default operator table.
See Builtin Operators.
#builtin-primitivetypesThe primitive types.
See Builtin Types.
#builtin-interfacesThe builtin generic interfaces.
See Builtin Types.
#builtin-functionsThe free functions, and the methods of each builtin type.
See Builtin Functions and Builtin Types.
#builtin-implementationsThe builtin interface implementations.
#builtin-intrinsicThe primitive number and Boolean operations - #builtin.intrinsic.ADD_U64_U64(a, b). See Intrinsics.
#builtin-implementationReady-made implementations of the context interfaces, to inject in place of a builtin value - inject clock := #builtin.implementation.FixedClock.new(someInstant). See Context.
the machine and the runtime library: memory, the endless loop, and the data tables and engines too big or too platform-specific to write out What the builtin types are built on - see Implementations for where each is used.
#builtin-foreverthe endless count 0, 1, 2, ... - the one unbounded sequence every open-ended loop is built on
#builtin-allocatesize bytes from &heapAllocator, aligned to alignment - the address of the first
#builtin-freegives back a block allocate handed out, by its first address
#builtin-addressofwhere a value is stored
#builtin-loadreads a T from memory
#builtin-storewrites a T to memory
#builtin-parsefloatcorrectly rounded decimal-to-binary conversion - the one number literals go through (T is F32 or F64)
#builtin-formatfloatthe shortest digits that parse back to the same value, or exactly precision decimals, correctly rounded
#builtin-unicodecategorythe General_Category, "Lu" - from UnicodeData
#builtin-unicodepropertya binary Unicode property, "ID_Start" - from the Unicode property tables
#builtin-unicodeupperfull case mapping - some code points map to several - from UnicodeData and SpecialCasing
#builtin-unicodelowerlowercase - some code points map to several
#builtin-graphemebreakswhere each extended grapheme cluster starts - from the segmentation tables (UAX #29)
#builtin-normalizecanonical / compatibility (de)composition - from the normalization tables (UAX #15)
#builtin-regexcompileparses a pattern (ECMAScript syntax; flags "i", "m", "s", "u", "x") into a backtracking program
#builtin-regexexecuteruns a program on text from start (only at start itself when anchored) - each group's span in code points, group 0 the whole match; undefined when nothing matches
#builtin-regexgroupsthe program's named groups, each with its group number
#builtin-zlibcompresszlib (RFC 1950) - the DEFLATE engine PNG images are stored with
#builtin-zlibdecompresszlibCompress the other way - a ParseError for data that is not zlib
#builtin-bytesuintthe unsigned integer width bytes (at most 6) wide at at - most significant first when big
#builtin-bytesputuintvalue (below 2^48) written width bytes wide at at - most significant first when big
#builtin-pixelsunpackwidth x height pixels in a layout - RGBA, RGB, BGRA, BGR, gray, gray and alpha, 16-bit samples, 1- to 8-bit palette indices and grays, 5-6-5 and 5-5-5 - from offset, as RGBA: each row stride bytes, the bottom one first when bottomUp; palette's RGBA quads for the indices, key the one transparent sample value (-1 for none) - undefined when the data runs short
#builtin-pixelspackRGBA pixels written in a layout - each row stride bytes, the bottom one first when bottomUp
#builtin-pixelsanalyze1 when any alpha isn't 255, 2 when any pixel isn't gray, 4 when any alpha isn't 0 or 255, 8 when any isn't 0
#builtin-pixelsfilledcount RGBA pixels, each the color 0xRRGGBBAA
#builtin-pixelscropthe w x h RGBA pixels at x, y of an image width wide
#builtin-pixelsflipRGBA pixels mirrored left to right when horizontal, top to bottom otherwise
#builtin-pixelsrotateRGBA pixels turned clockwise 1 to 3 quarter turns
#builtin-pixelsresizeRGBA pixels scaled - nearest neighbour, or smooth: averaged when shrinking, bilinear when growing, color weighted by alpha
#builtin-pixelsdrawsource's RGBA pixels drawn over target's with its top-left at x, y - clipped, blended source-over
#builtin-pngfilterPNG rows, each with the filter that makes its bytes smallest before it
#builtin-pngunfilterPNG's filtered rows from offset, undone - undefined when a filter isn't one or they run short
#builtin-adam7placean interlaced PNG's pass (0 to 6), as RGBA, put where it goes in the whole image's
#builtin-qoiencodecount RGBA pixels as QOI chunks, and QOI's end marker
#builtin-qoidecodecount RGBA pixels from QOI chunks at offset - undefined when they run short
#builtin-rleencodecount pixels of bpp bytes each as TGA's run-length packets
#builtin-rledecodecount pixels of bpp bytes each from TGA's run-length packets at offset - undefined when they run short
#builtin-lzwencodepalette indices LZW-coded as GIF does, in its sub-blocks
#builtin-lzwdecodecount palette indices from GIF's LZW sub-blocks at offset - what's missing left 0
#builtin-quantizecount RGBA pixels as indices into a palette of at most maxColors - each color its own when there are few enough, otherwise a median cut, Floyd-Steinberg dithered across rows width wide when dither; alpha under 128 transparent: [palette, indices, the transparent index or -1]
#builtin-jpegencodescanbaseline JPEG's entropy-coded scan of RGBA pixels - YCbCr (Y alone when gray), 4:2:0 when subsample; quant two tables of 64 (natural order), huffman four tables (each 16 counts and its values)
#builtin-jpegdecodescanone JPEG scan - baseline or progressive - added to coeffs (16-bit), its data at offset: where it ends, or -1 when it uses a Huffman table there isn't
#builtin-jpegfinisha JPEG's RGBA pixels from all its coefficients - dequantized, inverse-transformed, upsampled as libjpeg does, made RGB (transform 1 YCbCr, 0 RGB or CMYK, 2 YCCK)
#builtin-yuvencodeRGBA as planar YCbCr (BT.601, limited range; gray full range): Y, then Cb, then Cr - mode 0 4:2:0, 1 4:2:2, 2 4:4:4, 3 Y alone
#builtin-yuvdecodeplanar YCbCr at offset, as RGBA - undefined when the planes run short
#builtin-pcmdecodecount samples stored in an encoding - 8-bit unsigned and signed, 16-, 24- and 32-bit either endian, floats and doubles either endian, mu-law, A-law - from offset, as 32-bit floats; undefined when short
#builtin-pcmencode32-bit float samples stored in an encoding - rounded and clamped; G.711 as ffmpeg writes it
#builtin-samplesgainevery float sample times gain
#builtin-samplesmixsource's float samples times gain added to target's from sample at - as far as target goes
#builtin-samplesremixfloat samples of from channels as to channels - averaged to 1, 1 copied to all, otherwise each its own
#builtin-samplesresampleeach channel's float samples at toRate instead of fromRate - windowed sinc, 16 zero crossings a side
#builtin-samplespeakthe largest magnitude of any float sample - 0 for none
#builtin-samplesfromarraynumbers as 32-bit float samples
#builtin-samplestoarray32-bit float samples as numbers
#builtin-flacencodeFLAC frames of float samples as bits-bit integers, blockSize a channel each - the smallest of CONSTANT, VERBATIM, FIXED and LPC for each, mid/side when it helps: [the frames, the smallest frame's size, the largest's]
#builtin-flacdecodethe float samples of FLAC frames from offset - at most total a channel when it's more than 0; undefined when there are no frames there
Compile-time evaluation.
#comptime-callEvaluate the given expression at compile time and inline its result.
#comptime-bracecallEvaluate the given block at compile time and inline its result.
#comptime-typeofResolve to the expression's statically known type, computed at compile time.
what the compiler knows about the program's definitions - folded to a constant where the type or function is known at compile time, read from the tables the compiler emits otherwise What the builtin types are built on - see Implementations for where each is used.
#comptime-callsitewhere the current call was written, when locations are kept - "src/main.rfn:12:5"
#comptime-typenamethe name as written, with generics - "Array
#comptime-typenamedthe type written as name - "Point", "Shape.Circle" - from the same tables
#comptime-typegenericsits type arguments - [U8] for Array
#comptime-typefieldsfield names and types, in declaration order - empty unless a Struct or Tuple
#comptime-typevariantscases or members, in declaration order - empty unless an Enum or Union
#comptime-sizeofbytes a value occupies
#comptime-sametypethe same type, with the same generics
#comptime-isassignablethe type checker's own rule - a from-value fits where a to is expected
#comptime-implementsthere's an implement interface for type in scope
#comptime-interfacenamethe name it was declared under - "Comparable"
#comptime-interfacememberseach required member's name and type
#comptime-implementorsevery type with an implement block for it in scope
#comptime-sameinterfacethe same interface, with the same generics
#comptime-functionnamethe name it was defined under - undefined for a Lambda
#comptime-functionsignatureits own type, parameters and result included
#comptime-functionarityhow many parameters it takes
#comptime-ispureit's marked @pure
#comptime-partiala new function with the first argument fixed, taking the rest - it needs the argument list's shape
#comptime-currya chain of one-argument functions, one per parameter
#comptime-flipthe same function with its first two parameters swapped
Explicitly runtime evaluation.
#runtime-callDefer evaluation of the given expression to runtime, even if it could be computed at compile time.
#runtime-bracecallDefer evaluation of the given block to runtime.
#runtime-typeofResolve to the value's actual type as observed at runtime, rather than its statically known type.
the running program's own state - the values themselves, not their declarations What the builtin types are built on - see Implementations for where each is used.
#runtime-abortends the program with error, printing it and its trace() to &stderr - past &panicHandler, which is what the builtin one (AbortingPanicHandler) comes down to
#runtime-variantofwhich case an enum value is
#runtime-payloadofthe case's payload, positionally - a struct-like case's fields in order, empty for a unit case
#runtime-fieldsofa struct value's fields, in declaration order - or an enum case's, named as construct takes them ("0", "1", ... for a tuple case), so construct(variantOf(v), fieldsOf(v)) makes v again
#runtime-fieldvaluesoffieldsOf's values alone, in the same order - a struct's fields, an enum case's payload - without making the Map
#runtime-constructa value of type built from its fields by name - a missing or unknown field is an Error. An enum case's type is named with its enum, as variantOf gives it, and a tuple case's values are named "0", "1", ...
#runtime-tuplegetthe field at a position
#runtime-tupleappenda tuple of both values' fields, a's first
#runtime-invokejumps to f's code with args spread into its parameters
#runtime-samefunctionthe same code - and for a Lambda the same captured values, for a Method the same self
#runtime-boundselfthe value a Method was read from - a in a.method
#runtime-unbinda Method's code as a Function taking self as its first argument
#runtime-capturesa Lambda's captured variables, by name, as they are now
#runtime-schedulequeues task on the event loop, to run once &clock.now() reaches at. Tasks run one at a time, in the order they came due; with none due, the loop calls &clock.sleep until the next one is. A web page can't wait: there the page's own timers run the system clock's tasks, and the program goes on meanwhile
#runtime-nextframequeues task on the event loop, to run with the time, in milliseconds, once the display draws its next frame - a web page's; anywhere else once 16 ms have gone on &clock
#runtime-listentask kept for JavaScript to call back - a listener's events, a JsValue.callback's calls, a JavaScript promise settling - by the number this gives, which the host is told. It runs on the event loop, with what JavaScript hands it, and what it gives goes back; then the tasks that's made ready run, and an @app's components it changed render again
#runtime-unlistenthe task listen kept under number forgotten - JavaScript calling it does nothing from then on
#runtime-rununtilruns the event loop until done() is true - aborts when nothing's left to run and done() still isn't
#runtime-onthreadwork(..arguments) started on another of the host's threads: the arguments copied there, and the promise settled with the result copied back once the loop sees it done - undefined when the host has no thread to spare, or one of them can't be copied (see Promise.parallel)
#runtime-onthreadunsafethe same with the caller's context values copied to the thread too - Promise.parallelUnsafe's
#runtime-copya copy of value sharing nothing with it - what goes to another thread
#runtime-lockedf run with `value` (one shareAcrossThreads gave) locked - no other thread gets it until f ends; a thread that has it locked can lock it again
#runtime-waitforchangewaits until `value` (one shareAcrossThreads gave) is changed by another thread, or `ms` milliseconds pass - forever when negative
Reserved - has no members.
A macro whose body is another language's source. The body is checked by that language's own parser when the program compiles - a SQL syntax error is a compile error, pointing into the body - and becomes a typed value rather than a string. Inside it, #{ expression } splices in a Refingere value, each language in the one way that's safe for it: a bound parameter in SQL, escaped text in HTML, one quoted argument in a shell command. A value can't change the embedded code's structure, so injection can't happen. \#{ writes a literal #{.
#sqlA SQL statement as a typed, prepared query.
Query<Row> - a prepared statement, run through the database connection in context; run() gives a Table<Row>SELECT reading one @entity struct's table selects only its columns - Row is then that struct, when every field that isn't optional is selected. #SQL<Row> {{{ ... }}} names Row for any other query - a join, COUNT(*). Otherwise each row is a Map of its columns.#{ }? / $1), never text spliced into the statement - so a value can't change the query's shape, and SQL injection can't happen.#htmlAn HTML fragment as a value, built safely from data.
Html - a document fragment, rendered by its toString()#{ }Html - so nesting fragments works, and nothing else can inject markup. In an event attribute (onclick, oninput, ...) the value is a lambda, called when the event fires, with the event if it takes an argument - it only runs in a browser app, and toString() leaves it out. A component instance renders in place.#vueA Vue single-file component - template, script and style - written inline.
Component - a Vue component definition, ready to register or mountdefineProps.#{ }{{ }} interpolation for the component's reactive state - the two never clash, since #{ } isn't Vue syntax.#cssA CSS stylesheet as a value.
Stylesheet - parsed rules, rendered by toString()#{ }#wgslA WGSL shader for the GPU, as a value - see Graphics on the GPU.
Wgsl - a shader's source, what Gpu.shader compiles( ), [ ] and { } - balance. The GPU compiles the rest when the shader is made, and reports what doesn't on the host's console.#{ }Wgsl, its source spliced in whole, so a shader can be put together from pieces.#glslA GLSL shader, as a value - one stage per shader, as GLSL writes it.
Glsl - an OpenGL or Vulkan shader's source( ), [ ] and { } - balance. The rest is compiled by whatever takes the shader: a browser's WebGPU only takes WGSL, so a Glsl is for a host whose GPU reads GLSL, or for a tool that turns it into SPIR-V.#{ }Glsl, its source spliced in whole, so a shader can be put together from pieces.#hlslAn HLSL shader, as a value.
Hlsl - a Direct3D shader's source( ), [ ] and { } - balance; the shader compiler that takes it checks the rest.#{ }Hlsl, its source spliced in whole, so a shader can be put together from pieces.#mslA Metal shader, as a value.
Msl - a Metal shader's source( ), [ ] and { }, so [[ ]] attributes too - balance; Metal's compiler checks the rest.#{ }Msl, its source spliced in whole, so a shader can be put together from pieces.#spirvA SPIR-V module in its assembly text, as a value.
Spirv - a SPIR-V module, in the assembly text spirv-as reads%id = OpName ... or OpName ... - a ; comment, or blank. What the instructions mean is checked by the tool that assembles it.#{ }Spirv, its source spliced in whole, so a shader can be put together from pieces.#svgAn SVG image as a value, built safely from data.
Svg - a vector image, rendered by its toString()<svg> root, and every element and attribute is one SVG defines.#{ }#HTML: escaped text in a text position, an escaped, quoted value in an attribute position, and spliced in whole when the value is itself Svg. An Svg placed in #HTML is inline SVG.#jsonA JSON document as a typed value, parsed at compile time.
Json - the parsed document, with the literal's own shape as its type#{ }#yamlA YAML document as a typed value, parsed at compile time.
Arrayno and on stay strings.#{ }[...], a struct as {...} - so a value can't add keys or change the indentation around it.#tomlA TOML document as a typed value, parsed at compile time.
Array, a date-time an Instant#{ }[...], a struct as an inline table. Only in a value position, never a key or a table header.#csvA CSV table as a typed value, parsed at compile time.
Table<Row> - the header names the columns, which become Row's fieldsS64, F64, Boolean, else String - optional when a field is empty.#{ }#regexA regular expression compiled at compile time. Flags are written inline, at the start of the pattern: (?i). A short one fits in a string instead: #regex"...".
Regex - compiled once, when the program compilesParseError Regex(pattern) returns - and named groups become typed fields of each Match.#{ }Regex.escape would make it.#markdownMarkdown rendered to HTML when the program compiles.
Html - the rendered document, the same type #HTML makes#{ }#shellA shell command line, with arguments passed safely.
Command - not run until run(), which goes through the process context#{ }; can't split it or start a second command.#httpAn HTTP request - its method, URL, headers and body - written as it goes over the wire.
HttpRequest - not sent until send(), which goes through &http and gives a Promise<IOError ! Response>POST https://..., or the URL alone for a GET - the URL starting with http://, https://, / or a placeholder; every line up to the first blank one is a header, Name: value. What follows the blank line is the body, its indentation taken off.#{ }/, ?, & or space can't change where the request goes. Before the path (#{ base }/todos) it's text as it is. In a header's value, text, a line break turned into a space so it can't start another header. A placeholder that's the whole body is the body itself - Bytes stay bytes, Json is its JSON text; in the middle of a body, its text. A macro whose name is written straight against a string literal, with no space - see String Macro. The string is the macro's input: it's written like any string, in any quote style, and #{ expression } inside it is a placeholder for a Refingere value, as in the embedded languages. \#{ writes a literal #{. The string ends at its first unescaped closing quote, so a placeholder that needs quotes of its own goes in a string of the other style.
#string-macro-formatText with values in it: the string, with each #{ expression } replaced by that value's text. The same as joining the pieces with ++ and toString(), without writing them out - #format"#{ n } items" is n.toString() ++ " items".
String#{ }toString(). For a particular form, call a method inside the placeholder: #{ price.toString(2) } for two decimals, #{ n.toString(16) } for hexadecimal, #{ name.padEnd(10) } for a column.#string-macro-regexA short regular expression, written as a string. The string's own escapes still apply, but one it doesn't know - \d, \b, \. - is kept as written, so a pattern rarely needs its backslashes doubled. Flags go inline, at the start of the pattern: (?i), from i, m and s. Matching is always by code point. For a long pattern, or one full of quotes, use #REGEX {{{ }}}, which takes the body as written.
Regex - compiled once, when the program compilesParseError Regex(pattern) returns.#{ }Regex.escape would make it. Your own macros are code the compiler runs while compiling: they take source in and give source - or a finished value - back, in the place they were used. Each is an implement macro block, visible to the whole project, with one of five kind attributes:
| Kind | Used as | Its input | It returns |
|---|---|---|---|
@bodyMacro | #name {{{ ... }}} | the body | what goes in its place |
@stringMacro | #name"..." | the string | what goes in its place |
@deriveMacro | @derive(Name) | the struct or enum | implement blocks to add |
@attributeMacro | @name(...) | the definition it's on, and its own arguments | the definition to use instead |
@programMacro | never by name - it runs once | the whole program | code to add |
Input. The first parameter is the input, and its type picks the form it arrives in: a String of the text as written, an Array<Token> of it lexed, or a syntax tree - an Ast.Expression or Ast.Block for a body, the Ast.Struct, Ast.Function, ... for a derive or attribute macro, the whole Ast.Program for a program macro. A #{ } placeholder in a string or body arrives as written; Ast.splitPlaceholders separates it from the text. Parameters named arguments, attributes and site add an attribute macro's own arguments, the other attributes beside it, and where it was used.
Result. A returned String is Refingere source, read as if it were written where the macro was used - so a macro can build code with #format. Tokens and syntax trees go in as they are. Any other value is computed while compiling and becomes a constant, and a text value is returned as Ast.literal(text), since a plain String is source. An error is a compile error, pointing at the macro's use - or, with error "..." with node.span(), at the node it's about.
Phase. @phase picks when a macro runs: Lex, Parse, Analyze (every name resolved, across the program) or Typecheck (every expression's type known). A later phase knows more; an earlier one can change more. By default a macro runs as early as its input exists. The tree a macro works with - every Ast node, and Span - is on Syntax Tree, and every kind of Token on Tokens.
Writing a macro walks through an example of each kind.
A @programMacro is the general form: it isn't used anywhere by name. It runs once per compilation with the whole program as an Ast.Program, picks what it wants with program.find<Kind>(condition) - any kind of node, by any condition: its name, its attributes, its fields, the file it's in, and from Typecheck on, its type - and returns code to add, as source or definitions. The additions land in the macro's own folder, as if in one more file there. A program macro only adds code: changing a definition is an attribute macro's job. Every program macro at a phase sees the same program, without the others' additions, so they don't depend on each other's order.
Both keep working as the program grows: a new ...Event struct, or a new @entity, gets its code the next time the program compiles, with nothing to register.
#comptime.definitionsWith("name") finds every definition in the program carrying an attribute - each function, struct, const, ... marked @name(...), anywhere in the project. Each result has its name, kind, file, the attribute's arguments (evaluated while compiling), its syntax tree, and the definition itself as a value to call or use. The attribute can be one nothing else looks at: plain metadata becomes a registry, with no list to keep in step by hand. Macros can use it from the Analyze phase on, and in ordinary code it's a constant list. #comptime.program() goes further, giving any macro or #comptime(...) code the whole Ast.Program - the same one a program macro gets.
#comptime-definitionswithEvery definition in the program carrying the attribute named - each result a Definition, with name(), kind(), file(), the attribute's arguments(), its syntax tree as ast(), and the definition itself as value().
#comptime-programThe whole program's syntax tree, as an Ast.Program: its files(), every definitions(), and find for every node of a kind that a condition accepts. For macros and #comptime(...) code, from the Analyze phase on.