Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Builtins

Generated from the language spec, which is normative.

Builtins are available without import. They are resolved only when the name is not bound by a variable in scope or a declared function; such a binding shadows the builtin entirely (a shadowed builtin is not callable through any other path).

print

print(v1, ..., vn)

Takes zero or more arguments of any single-value types, renders each canonically, joins them with single spaces, and writes the result followed by a line feed to standard output. Canonical rendering (shared by print, the %v verb, and str()):

TypeRendering
intdecimal
floatshortest decimal that round-trips; integral values render without a fractional part (3.0 renders as 3); infinities as inf/-inf, NaN as NaN
booltrue / false
strthe string itself, unquoted
list[e1, e2, ...], elements rendered recursively
map{k1: v1, k2: v2} in insertion order
structName{f1: v1, f2: v2} in declaration order
nonenone
errorerror(<msg>)
pyPython str() of the object
fnfn

printf and sprintf

printf(format, a1, ..., an)          // writes to standard output, no implicit newline
sprintf(format, a1, ..., an) str     // returns the formatted string

The format string uses Go-style verbs:

VerbArgument typeOutput
%vanycanonical rendering (section 14.1)
%dintdecimal
%sstrthe string
%tbooltrue / false
%qstrdouble-quoted, backslash-escaped
%ffloatfixed-point, default 6 fractional digits
%%noneliteral %

A verb may carry a minimum width (%5s) and a precision (%.2f), both decimal digit sequences, in the form %[width][.precision]verb. Width pads on the left with spaces to the given count of characters (not bytes). Precision is honored by %f; on other verbs it is accepted and ignored. There is no left-align or zero-pad flag. A width or precision exceeding the implementation’s pad limit (2^20 in the reference implementation) is rejected: a compile-time diagnostic when the format string is a literal (section 14.3), a fault otherwise (chapter 12).

Static and dynamic format checking

When the format argument is a string literal, the format is checked at compile time: verb count must equal argument count, each argument’s type must match its verb, verbs must be from the table, and the format must not end inside a verb. Violations are compile-time errors.

When the format is not a literal, the same checks happen at runtime and a violation is a fault (chapter 12).

len

len(x) int

For str, the number of characters; for list, the element count; for map, the entry count. Any other argument type is a compile-time error.

args

args() []str

Returns the program’s arguments: everything after the source file on the command line (nv prog.nv a b and nevla run prog.nv a b both yield ["a", "b"]). Takes no arguments. In contexts with no command line (tests, embedding) the list is empty.

input

input(prompt str) (str, error?)

Writes prompt to standard output (no trailing newline, flushed), then reads one line from standard input. The returned string excludes the line terminator. End of input and read failures are error values, not faults (eof on end of input). When a program runs through the CLI runner its output is streamed unbuffered, so a prompt is visible before input blocks.

ord

ord(c str) int

The Unicode code point (the character’s number) of c, which must be exactly one character; any other argument value is a runtime fault.

chr

chr(n int) str

The one-character string for the Unicode code point n. A value that is not a valid Unicode scalar (negative, greater than 0x10FFFF, or a surrogate) is a runtime fault. chr(ord(c)) == c for every one-character c.

append

append(xs []T, v1 T, ..., vn T) []T

A fresh list: xs with the values appended, as in Go’s idiom xs = append(xs, v). The first argument must be a list; every following value must be assignable to its element type. Zero values yield a plain copy. The original list is never modified; other names bound to it see growth only through rebinding (chapter 11).

clone

clone(x []T) []T
clone(x map[K]V) map[K]V

A one-level copy of a list or map (chapter 11): the container is new, its elements copy by their kinds, exactly Go’s slices.Clone/maps.Clone. Applying clone to a value type is a compile-time error; value types already copy.

Methods on builtin types

All receivers are unchanged; results are new values.

String methods

Receiver str. Positions and counts are in characters.

  • split(sep str) []str — split on the separator.
  • trim() str — strip leading and trailing white space.
  • upper() str, lower() str — case conversion.
  • contains(sub str) bool, starts_with(prefix str) bool, ends_with(suffix str) bool — substring, prefix, and suffix tests.
  • replace(from str, to str) str — replace all occurrences.
  • find(sub str) int? — character index of the first occurrence, none if absent.
  • fields() []str — split on runs of white space; no empty fields.
  • lines() []str — split on line feeds; a trailing line feed adds no empty line.
  • trim_prefix(p str) str, trim_suffix(p str) str — remove a leading or trailing p if present, else unchanged.
  • chars() []str — the characters as one-character strings.
  • repeat(n int) str — the string tiled n times; negative n faults, as does a result exceeding the implementation’s size limit (2^30 bytes in the reference implementation).
fn main() {
    s := "  the nevla book  "
    t := s.trim()
    print(t.upper())                  // THE NEVLA BOOK
    print(t.split(" ").join("-"))     // the-nevla-book
    print(t.replace("book", "spec"))  // the nevla spec
    i := t.find("nevla")
    if i != none {
        print(i)                      // 4
    }
    print("na".repeat(2) + " batman") // nana batman
    print(len("héllo"))               // 5: characters, not bytes
}

▸ run it in the playground

List methods

Receiver []T.

  • map(f fn(T) U) []U — apply f to each element.
  • filter(f fn(T) bool) []T — keep elements where f is true.
  • each(f fn(T)) — call f on each element; no result.
  • sum() TT must be int or float; the sum of the elements. Integer overflow faults (chapter 12). Summing an empty []int yields 0; the result of summing an empty []float is unspecified in v1 (the reference implementation yields a value that faults on later float use).
  • sorted() []TT must be int, float, or str; a fresh ascending list.
  • sorted_by(before fn(T, T) bool) []T — a sorted copy per the comparator; the sort is stable.
  • contains(v T) bool — structural membership (section 11.2).
  • join(sep str) strT must be str; concatenation with the separator.
fn main() {
    xs := [3, 1, 4, 1, 5]
    print(xs.sorted())                          // [1, 1, 3, 4, 5]
    print(xs.map(fn(x) { x * 10 }).sum())       // 140
    print(xs.filter(fn(x) { x > 2 }))           // [3, 4, 5]
    print(xs.contains(4))                       // true
    print(xs.sorted_by(fn(a, b) { a > b }))     // [5, 4, 3, 1, 1]
}

▸ run it in the playground

Map methods

Receiver map[K]V. Iteration order is insertion order (section 5.3).

  • keys() []K — the keys, in insertion order.
  • values() []V — the values, in insertion order.
  • has(k K) bool — key presence.
  • delete(k K) — removes k in place, Go’s delete; the remaining order is preserved.
fn main() {
    m := map[str]int{"b": 2, "a": 1}
    print(m.keys())      // [b, a]: insertion order, not sorted
    print(m.has("a"))    // true
    m.delete("b")
    print(m.values())    // [1]
}

▸ run it in the playground