Interfaces

Every interface the language has built in - see Interface Definition and Implement an Interface for how to declare and implement one. They're grouped by what they're for: the operators each one backs, converting to and from text, building and walking collections, properties of the values themselves, and the ones the context values are typed by - implement one of those and inject it to replace the builtin value. Each card lists the members a type has to provide to implement it; the Types page lists which interfaces each builtin type implements.

Interfaces as values

Interface

#interface
Interfaces

A set of functions a type promises to provide - see Interface Definition. The builtin ones follow.

Sourceown members

Members (4)

an interface as a value

Implements Equatable, Hashable, ToString

Methods

  • name(): Stringas declared - "Comparable" source
  • members(): Map<String, Type>every Method / Function it requires source
  • implementors(): Array<Type>types in scope implementing it source
  • isImplementedBy(type: Type): Booleantype has an implement of it in scope source

Operators

Equatable

#equatable
Interfaces

Backs ==, !=, and value alternation/combination (|, &).

Required members of Equatable :(1)

Methods

  • equals(other: Self): Booleansame value - a == b

Comparable

#comparable
Interfaces

Backs <, <=, > and >= - and min, max, sorting and clamp wherever they take a Comparable.

Required members of Comparable :(1)

Methods

  • compare(other: Self): OrderingLess, Equal or Greater - the order of self and other

Numeric

#numeric
Interfaces

Backs the arithmetic operators - + - * / // % ^ - and prefix - and +. Its zero and one are what sum and product start from.

Required members of Numeric :(11)

Functions

  • zero(): Selfadditive identity - 0
  • one(): Selfmultiplicative identity - 1

Methods

  • add(other: Self): Self+
  • subtract(other: Self): Self-
  • multiply(other: Self): Self*
  • divide(other: Self): Self/
  • floorDivide(other: Self): Self//
  • remainder(other: Self): Self%
  • power(exponent: Self): Self^
  • negate(): Selfprefix -
  • plus(): Selfprefix +

Scalable<Factor>

#scalable
Interfacesgeneric

Backs a * factor, factor * a and a / factor when factor is a plain Factor rather than another Self - e.g. Duration.seconds(2) * 1.5 or a Vector times a number. Division is scale by the reciprocal.

Required members of Scalable<Factor> :(1)

Methods

  • scale(factor: Factor): Selfevery part times factor

Bitwise

#bitwise
Interfaces

Backs bor, bxor, band, shl, shr and prefix ~. Implemented by every integer type and by Mask.

Required members of Bitwise :(6)

Methods

  • bor(other: Self): Selfa bor b
  • bxor(other: Self): Selfa bxor b
  • band(other: Self): Selfa band b
  • bnot(): Self~a
  • shl(count: U64): Selfa shl b
  • shr(count: U64): Selfa shr b

Logical

#logical
Interfaces

Backs and, or, xor, iff and prefix not - for Boolean, Trilean's three-valued logic, or a type of your own (e.g. fuzzy truth values). Only Boolean short-circuits: for any other implementor both sides are evaluated before the method is called.

Required members of Logical :(5)

Methods

  • not(): Selfnot a
  • and(other: Self): Selfa and b
  • or(other: Self): Selfa or b
  • xor(other: Self): Selfa xor b
  • iff(other: Self): Selfa iff b

Concatenable<Other, Result>

#concatenable
Interfacesgeneric

Backs a ++ b (and set a ++= b) - one value's contents followed by another's. Other and Result default to Self; Array takes any Iterable on the right, and a Tuple's result is both tuples' fields together. Implemented by text, Bytes, Array, Stack, Queue, Deque, Set (union), Map (the right side's value wins), Table and Tuple.

Required members of Concatenable<Other:=Self, Result:=Self> :(1)

Methods

  • concat(other: Other): Resulta ++ b

Indexable<Key, Value>

#indexable
Interfacesgeneric

Backs a[b], set a[b] := value, and superscript/subscript indexing.

Required members of Indexable<Key, Value> :(2)

Methods

  • get(key: Key): Value?a[b], undefined when there's nothing at key
  • set(key: Key, value: Value): Error ! UndefinedSet a[b] := value

Callable<Args, Result>

#callable
Interfacesgeneric

Can be called like a function: value(args).

Required members of Callable<Args, Result> :(1)

the general interfaces (see Interfaces)

Method - called on a value, has access to self; Function - called on the type, no self

Self - the type implementing the interface

Methods

  • call(args: Args): Resultvalue(args)

Castable<Type>

#castable
Interfacesgeneric

Backs a as Type.

Required members of Castable<Type> :(1)

Methods

  • cast(): Typeself as Type

Conversion

ToString

#tostring
Interfaces

Can be turned into a String - what print, format and join use.

Required members of ToString :(1)

Methods

  • toString(): Stringthe value as text - #format and #{ } use it

FromString

#fromstring
Interfaces

Can be read back from text - the other way from ToString. Type.parse(text) and text.parse<Type>() both call it, so a generic function can parse any T: FromString, e.g. a config value or a command-line argument.

Required members of FromString :(1)

Functions

  • parse(text: String): ParseError ! Selfthe value the text writes, a ParseError when it isn't one

Collections and iteration

Iterable<Type>

#iterable
Interfacesgeneric

Backs ||>, .. spread, and loops - produces an Iterator<Type>.

Sourceown members

Required members of Iterable<Type> :(1)

Methods

  • iterator(): Iterator<Type>a fresh iterator over its elements, from the start
Members of Iterable<Type>(29)

shared by every collection below - their own blocks only list what they add or change

Implements Iterable<Type>, FromIterable<Type>, Collection<Type>, Sized<Type>, ToString, Default (empty), Clone - and Equatable, Hashable when Type does

Methods

  • isEmpty(): Booleanno elements source
  • count(where: Lambda<Type, Boolean>): U64elements where says yes to source
  • contains(item: Type): Booleana in b source
  • any(where: Lambda<Type, Boolean>): Booleanwhere says yes to at least one - false when empty source
  • all(where: Lambda<Type, Boolean>): Booleanwhere says yes to every one - true when empty source
  • none(where: Lambda<Type, Boolean>): Booleanwhere says yes to none - true when empty source
  • find(where: Lambda<Type, Boolean>): Type?first element where says yes to source
  • forEach(f: Lambda<Type, Undefined>): Undefinedruns f on each element, in order source
  • reduce<Result>(initial: Result, f: Lambda<(Result, Type), Result>): Resultf applied left to right, starting from initial source
  • fold(f: Lambda<(Type, Type), Type>): EmptyError ! Typereduce starting from the first element source
  • min(): EmptyError ! TypeType: Comparable source
  • max(): EmptyError ! TypeType: Comparable source
  • minBy<Key: Comparable>(key: Lambda<Type, Key>): EmptyError ! Typeelement with the smallest key - the first of equals source
  • maxBy<Key: Comparable>(key: Lambda<Type, Key>): EmptyError ! Typeelement with the largest key - the first of equals source
  • sum(): TypeType: Numeric, zero() when empty source
  • product(): TypeType: Numeric, one() when empty source
  • average(): EmptyError ! FloatType: Numeric source
  • median(): EmptyError ! FloatType: Numeric - the middle element, the average of the two middle ones for an even count source
  • percentile(p: Float): EmptyError ! FloatType: Numeric - p from 0 to 100, between the two nearest elements when it falls between them source
  • variance(): EmptyError ! FloatType: Numeric - the mean squared distance from the average, of the whole population source
  • standardDeviation(): EmptyError ! FloatType: Numeric - the square root of variance() source
  • frequencies(): Map<Type, U64>Type: Hashable - how many times each element occurs, in the order each first did source
  • groupBy<Key: Hashable>(key: Lambda<Type, Key>): Map<Key, Array<Type>>elements by key, each group in order source
  • partition(where: Lambda<Type, Boolean>): (Array<Type>, Array<Type>)(those where says yes to, the rest) source
  • join(separator: String := ""): StringType: ToString source
  • toArray(): Array<Type>elements in order source
  • toSet(): Set<Type>Type: Hashable source
  • toMap<Key, Value>(entry: Lambda<Type, (Key, Value)>): Map<Key, Value>a Map from each element's (key, value) - later keys win source
  • @writes(self)clear(): Undefinedremoves every element source

FromIterable<Type>

#fromiterable
Interfacesgeneric

Can be built from a sequence of Type - the other way from Iterable. Iterator's collectInto<Target>() calls it, so a pipeline can end in any collection: a Set, a Map from (Key, Value) pairs, a String from codepoints.

Required members of FromIterable<Type> :(1)

Functions

  • fromIterable(items: Iterable<Type>): Selfbuilt from items, in order

Collection<Type>

#collection
Interfacesgeneric

Holds a number of elements, and can tell whether it holds a given one.

Required members of Collection<Type> :(2)

Methods

  • contains(item: Type): Booleanitem is one of its elements - a in b
  • iterator(): Iterator<Type>each element in turn

Sized<Type>

#sized
Interfacesgeneric

Has a known number of elements.

Required members of Sized<Type> :(2)

Methods

  • size(): U64how many elements
  • isEmpty(): Booleansize() == 0

Steppable

#steppable
Interfaces

Can step to a next value - what lets a Range run over a non-numeric type.

Required members of Steppable :(2)

Methods

  • next(): Selfthe value after self
  • previous(): Selfthe value before self

Values

Bounded

#bounded
Interfaces

Has a smallest and a largest value: Type.min() and Type.max(). Useful as the starting point of a running minimum or maximum, and for checking a value fits before a cast. Every integer type, every float type (their finite range) and Codepoint implement it.

Required members of Bounded :(2)

Functions

  • min(): Selfsmallest value
  • max(): Selflargest value

Default

#default
Interfaces

Has a default instance - used by @singleton, injection, and @require's default.

Required members of Default :(1)

Functions

  • default(): Selfthe default value

Hashable

#hashable
Interfaces

Can be a Set element or a Map key.

Required members of Hashable :(1)

Methods

  • hash(): U64the same for equal values - what Set and Map file it under

Clone

#clone
Interfaces

Can make an independent copy of a value.

Required members of Clone :(1)

Methods

  • clone(): Selfa copy sharing nothing with self

Copy

#copy
Interfaces

Copied implicitly instead of shared.

Required members of Copy :(0)

Context

OutputStream

#outputstream
Interfaces

What &stdout and &stderr are: somewhere bytes and text can be written.

Required members of OutputStream :(3)

the types of the builtin context values (see Context) - implement one and inject it to replace the builtin

Methods

  • @effects(self)write(bytes: Bytes): IOError ! Undefinedwrites the bytes as they are
  • @effects(self)writeText(text: String): IOError ! Undefinedwrites the text, UTF-8 encoded
  • @effects(self)flush(): IOError ! Undefinedpushes out anything buffered

InputStream

#inputstream
Interfaces

What &stdin is: somewhere bytes and lines can be read from.

Required members of InputStream :(3)

Methods

  • @effects(self)read(count: U64): IOError ! Bytesup to count bytes, empty at end of input
  • @effects(self)readLine(): IOError ! String?undefined at end of input
  • @effects(self)readAll(): IOError ! Byteseverything left until end of input

Clock

#clock
Interfaces

What &clock is: the current time, and a way to wait.

Required members of Clock :(2)

Methods

  • @reads(self)now(): Instantthe current time
  • @effects(self)sleep(duration: Duration): Undefinedwaits for duration - with nothing else to run, the program idles

Random

#random
Interfaces

What &random is: a source of random numbers.

Required members of Random :(3)

Methods

  • @writes(self)nextU64(): U64uniform over all of U64
  • @writes(self)nextF64(): F64uniform in [0, 1)
  • @writes(self)between(range: Range<Integer>): Integeruniform within the range

Environment

#environment
Interfaces

What &env is: named text variables, read and written.

Sourceown members

Required members of Environment :(3)

Methods

  • @reads(self)get(name: String): String?undefined when not set
  • @writes(self)set(name: String, value: String): Undefinedsets name to value
  • @reads(self)all(): Map<String, String>every variable, by name
Provided members of Environment :(1)

Methods

  • @reads(self)settings<Settings: Struct>(defaults: Settings, prefix: String := ""): ParseError ! Settingsdefaults with each field the variable named after it says - port from PORT, maxConnections from MAX_CONNECTIONS, after prefix ("APP_" reads APP_PORT) - parsed as the type of the field's default value (numbers, Boolean, Duration, Instant, Color, String); a field without a variable keeps its default, and a value that doesn't parse is a ParseError naming the variable source

FileSystem

#filesystem
Interfaces

What &fs is: files and directories, read, written and listed.

Sourceown members

Required members of FileSystem :(9)

Methods

  • @effects(self)read(path: String | Path): IOError ! Bytesthe whole file as bytes
  • @effects(self)readText(path: String | Path): IOError ! Stringthe whole file as UTF-8 text
  • @effects(self)write(path: String | Path, bytes: Bytes): IOError ! Undefinedcreates or replaces the file
  • @effects(self)writeText(path: String | Path, text: String): IOError ! Undefinedcreates or replaces the file, UTF-8 encoded
  • @effects(self)list(path: String | Path): IOError ! Array<String>entry names directly inside a directory
  • @effects(self)exists(path: String | Path): Booleana file or directory is there
  • @effects(self)isDirectory(path: String | Path): Booleanit's there and a directory
  • @effects(self)createDirectory(path: String | Path): IOError ! Undefinedcreates it, and any missing parents
  • @effects(self)remove(path: String | Path): IOError ! Undefineddeletes a file or a directory, with everything in it
Provided members of FileSystem :(1)

Methods

  • @effects(self)glob(pattern: String, from: String | Path := "."): IOError ! Array<String>every path under from that pattern matches (see Path.matchesGlob), relative to from and sorted source

Logger

#logger
Interfaces

What &logger is: somewhere structured log entries go. An implementation only writes log - debug, info, warn and error come with the interface.

Sourceown members

Required members of Logger :(1)

Methods

  • @effects(self)log(level: LogLevel, message: String, fields: Map<String, Unknown>): Undefinedone entry - the one method an implementation writes
Provided members of Logger :(4)

Methods

  • @effects(self)debug(message: String, fields: Map<String, Unknown> := Map.of()): Undefinedlog(Debug, message, fields) source
  • @effects(self)info(message: String, fields: Map<String, Unknown> := Map.of()): Undefinedlog(Info, message, fields) source
  • @effects(self)warn(message: String, fields: Map<String, Unknown> := Map.of()): Undefinedlog(Warn, message, fields) source
  • @effects(self)error(message: String, fields: Map<String, Unknown> := Map.of()): Undefinedlog(Error, message, fields) source

Allocator

#allocator
Interfaces

What &heapAllocator is: where blocks of memory come from and go back to.

Required members of Allocator :(3)

Methods

  • @writes(self)allocate(size: U64): OutOfMemoryError ! Bytesa fresh block of size bytes
  • @writes(self)resize(block: Bytes, size: U64): OutOfMemoryError ! Bytesthe block grown or shrunk to size - its contents kept up to the smaller size, possibly moved
  • @writes(self)free(block: Bytes): Undefinedgives a block back

Database

#database
Interfaces

What &database is: the connection #SQL queries run through - rows selected, rows changed.

Required members of Database :(2)

what #SQL queries run through - see Query

Methods

  • @effects(self)query(sql: String, parameters: Array<Unknown>): IOError ! Array<Map<String, Unknown>>the rows selected
  • @effects(self)execute(sql: String, parameters: Array<Unknown>): IOError ! U64how many rows changed

HttpClient

#httpclient
Interfaces

What &http is: where HttpRequests are sent - send gives a promise of the server's Response, or an IOError when none came.

Required members of HttpClient :(1)

Methods

  • @effects(self)send(request: HttpRequest): Promise<IOError ! Response>the server's answer, once it's come - whatever its status, a 404 too; an IOError when none came (no network, a refused connection, a name that doesn't resolve)

SnapshotStore

#snapshotstore
Interfaces

What &snapshots is: where snapshot tests keep their texts, by name. An implementation writes read, write and updating - check, what a test calls, comes with the interface.

Sourceown members

Required members of SnapshotStore :(3)

Methods

  • @effects(self)read(name: String): IOError ! String?the text kept under name - undefined when there's none yet
  • @effects(self)write(name: String, text: String): IOError ! Undefinedkeeps text under name, replacing what was there
  • @reads(self)updating(): Booleanwhether a text that differs replaces the kept one instead of failing - what --update-snapshots turns on
Provided members of SnapshotStore :(1)

Methods

  • @effects(self)check(name: String, actual: String): SnapshotError ! Undefinedpasses when actual is the text kept under name; keeps it when there's none yet (or when updating), and is a SnapshotError showing the first line that differs otherwise source

PanicHandler

#panichandler
Interfaces

What &panicHandler is: where a panic, todo, unreachable or a too-deep call ends up - it never returns.

Required members of PanicHandler :(1)

Methods

  • @effects(self)handle(error: Error): Neverpanic, todo, unreachable, Optional.expect and a too-deep call end here