#runtime
These are the host primitives. They are in scope everywhere without an import, and their
<type><Op>names (stringToUpper,intToString) mark them as the primitive layer. Prefer the library name where one exists (string.toUpper,string.toFloat), and reach for a name on this page only when no library module covers it.
The host primitives.
Every name here is an extern implemented by the runtime, in scope in
every program without an import. Most have a friendlier form in a
library module (string.toUpper over stringToUpper, io.readLines
over readFile); use this page when no library module covers what you
need.
An effect on a return type (<Stdout>, <FileRead>, <Net>,
<IO>) names what the primitive touches. A primitive with no effect is
pure. Mutation of a Ref or an array carries no effect.
#Output
#putStr
putStr : String -> <Stdout> UnitWrites a string to standard output.
#putStrLn
putStrLn : String -> <Stdout> UnitWrites a string and a newline to standard output.
#ePutStr
ePutStr : String -> <Stderr> UnitWrites a string to standard error.
#ePutStrLn
ePutStrLn : String -> <Stderr> UnitWrites a string and a newline to standard error.
#flushStdout
flushStdout : Unit -> <Stdout> UnitFlushes buffered standard output.
#Input
#readLine
readLine : Unit -> <Stdin> StringReads one line from standard input, without its newline. Bytes that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#readLineOpt
readLineOpt : Unit -> <Stdin> Option StringReads one line from standard input, or None at end of input. Bytes
that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#readAll
readAll : Unit -> <Stdin> StringReads all of standard input. Bytes that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#readExactly
readExactly : Int -> <Stdin> Option StringReads exactly the given number of bytes from standard input, or None
at end of input or on a short read. Like every string read from outside the
program, each ill-formed UTF-8 sequence becomes U+FFFD, so the result's
UTF-8 length can differ from the count.
#Mutable references
#Ref
Ref : a -> Ref aA new mutable cell holding a value. Read it with !r and write it
with r := v.
#Files
#readFile
readFile : (path : String) -> <FileRead path> Result String StringThe contents of a file as a string, or Err with the host's message.
A file that is not valid UTF-8 is an Err naming the path; read it with
readFileBytes.
#readFileBytes
readFileBytes : (path : String) -> <FileRead path> Result String (Array Int)The contents of a file as bytes, 0 to 255 each, or Err with the
host's message.
#writeFile
writeFile : (path : String) -> String -> <FileWrite path> Result String UnitWrites a string to a file, replacing any existing contents.
#writeFileBytes
writeFileBytes : (path : String) -> Array Int -> <FileWrite path> Result String UnitWrites bytes, 0 to 255 each, to a file, replacing any existing
contents.
#writeFileMode
writeFileMode : (path : String) -> Int -> String -> <FileWrite path> Result String UnitWrites a string to a file, replacing any existing contents, and leaves
the file at exactly the permission bits the given mode names (384 is
rw-------, 420 is rw-r--r--).
The contents never exist at a wider mode: the mode is set on the open file before the first byte is written, so neither the process umask nor a pre-existing file's own mode can widen the result.
#appendFile
appendFile : (path : String) -> String -> <FileWrite path> Result String UnitAppends a string to a file, creating it when it does not exist.
#fileExists
fileExists : (path : String) -> <FileRead path> BoolWhether a path exists.
#fileMode
fileMode : (path : String) -> <FileRead path> Result String IntA path's permission bits, 0 to 4095 (384 is rw-------), or
Err with the host's message. Symbolic links are followed.
#canonicalizePath
canonicalizePath : (path : String) -> <FileRead path> StringThe absolute path with ., .., and symbolic links resolved. The
input, unchanged, when it cannot be resolved. A resolved path whose bytes
are not valid UTF-8 reads with U+FFFD in their place, and so may not name
the entry it came from.
#listDir
listDir : (path : String) -> <FileRead path> Result String (List String)The names of the entries in a directory. A name whose bytes are not valid UTF-8 reads with U+FFFD in their place, so two such names can read alike and a returned name may not open the entry it came from.
#makeDir
makeDir : (path : String) -> <FileWrite path> Result String UnitCreates a directory.
#removeFile
removeFile : (path : String) -> <FileWrite path> Result String UnitDeletes a file.
#rename
rename : (src : String) -> (dst : String) -> <FileWrite src, FileWrite dst> Result String UnitMoves or renames a path.
#fsync
fsync : (path : String) -> <FileWrite path> Result String UnitFlushes a path's contents to durable storage. Works on a regular file or
a directory; the durability of a rename is a property of the containing
directory, not of either file.
#removeDir
removeDir : (path : String) -> <FileWrite path> Result String UnitRemoves an empty directory.
#statFile
statFile : (path : String) -> <FileRead path> Result String (Int, Bool, Bool, Float)A path's size in bytes, whether it is a directory, whether it is a
regular file, and its modification time in seconds. fs.stat returns the
same as a record.
#Processes and environment
#args
args : Unit -> List StringThe command-line arguments after the program name. Bytes that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#getEnv
getEnv : (name : String) -> <Env name> Option StringThe value of an environment variable, or None when it is unset.
Bytes that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#executablePath
executablePath : Unit -> <Env> StringThe absolute path of the running executable. Bytes that are not valid UTF-8 read as U+FFFD, one per ill-formed sequence.
#runCommand
runCommand : (program : String) -> List String -> <Exec program> Result String (Int, String, String)Runs a program with arguments and waits for it. Ok carries the exit
code, the captured standard output, and the captured standard error; a
non-zero exit code is still Ok. Err carries the host's message when
the program could not be started. The captured output is read as UTF-8:
bytes that are not valid UTF-8 read as U+FFFD, so output that is binary
data does not come back unchanged.
#exit
exit : Int -> UnitEnds the program with an exit code.
#panic
panic : String -> aAborts the program with a message. Panics cannot be caught.
#Networking
#netResolve
netResolve : (host : String) -> <Net host> Result String (List String)The numeric addresses a host name resolves to.
#netTcpConnect
netTcpConnect : (host : String) -> Int -> <Net host> Result String (Socket host)Opens a TCP connection to a host and port.
#netTcpListen
netTcpListen : (host : String) -> Int -> <Net host> Result String (ListenSocket host)Starts listening for TCP connections on an address and port. Port 0
picks a free port.
#netListenPort
netListenPort : ListenSocket a -> <Net a> Result String IntThe port a listener is bound to. Use it after listening on port 0.
#netTcpAccept
netTcpAccept : ListenSocket a -> <Net a> Result String (Socket a)Waits for the next connection on a listener. The connection is at the listener's authority: it is reached through the address the listener was granted.
#netSend
netSend : Socket h -> Array Int -> <Net h> Result String IntSends bytes on a connection. The result is the number of bytes written, which may be fewer than given.
#netSendFrom
netSendFrom : Socket h -> Array Int -> Int -> <Net h> Result String IntSends bytes starting at the given offset into the array. The result is the number of bytes written, which may be fewer than given and is limited to 64 KiB per call so a loop can retain one array while advancing through it.
#netRecv
netRecv : Socket h -> Int -> <Net h> Result String (Array Int)Receives up to the given number of bytes from a connection. An empty array means the other side has closed.
#netShutdown
netShutdown : Socket h -> Int -> <Net h> Result String UnitShuts down one or both directions of a connection: 0 for reading,
1 for writing, 2 for both.
#netClose
netClose : Socket h -> <Net h> Result String UnitCloses a connection.
#netCloseListener
netCloseListener : ListenSocket a -> <Net a> Result String UnitCloses a listener.
#netSetTimeout
netSetTimeout : Socket h -> Int -> <Net h> Result String UnitSets a connection's send and receive timeout in milliseconds. 0
means no timeout.
#socketFd
socketFd : Socket h -> IntThe descriptor number of a connection, for ioPoll. The number grants
nothing: every other extern takes the socket itself.
#listenSocketFd
listenSocketFd : ListenSocket a -> IntThe descriptor number of a listener, for ioPoll.
#pdsSignalStart
pdsSignalStart : Unit -> <Signal> Result String IntInstalls an opt-in SIGTERM handler for a native PDS, returning a pipe descriptor readable on shutdown. A binary that never calls this retains the operating system's default signal behavior. Call once after bind.
#pdsSignalRequested
pdsSignalRequested : Unit -> <Signal> BoolWhether SIGTERM has been observed since pdsSignalStart. Stays true;
the descriptor remains readable. Only call from ordinary task context.
#ioPoll
ioPoll : Array Int -> Array Int -> Int -> <Clock> Result String (Array Int)Waits until any of the descriptors is ready, or the timeout in
milliseconds passes (-1 waits forever). The interests are parallel to the
descriptors: bit 1 asks for readable, bit 2 for writable. The result is parallel too: bit 1 readable, bit 2 writable,
both bits on an error or hangup so a retry surfaces the error. A wait
reaches no endpoint: it reads and writes nothing on any descriptor it
watches, so it is a timed wait, charged as the clock.
#netSetNonblock
netSetNonblock : Socket h -> Bool -> <Net h> Result String UnitSwitches a connection's non-blocking mode on or off.
#netSetNonblockListener
netSetNonblockListener : ListenSocket a -> Bool -> <Net a> Result String UnitSwitches a listener's non-blocking mode on or off.
#netTryAccept
netTryAccept : ListenSocket a -> <Net a> Result String (Option (Socket a))netTcpAccept that returns None instead of blocking.
#netConnectStart
netConnectStart : (host : String) -> Int -> <Net host> Result String (Socket host)netTcpConnect that returns as soon as the handshake is under way. The
result is a non-blocking socket that is not connected yet: wait for it
to become writable, then ask netConnectCheck whether it arrived. Name
resolution still blocks.
#netConnectCheck
netConnectCheck : Socket h -> <Net h> Result String (Option Unit)Whether a socket from netConnectStart has finished its handshake.
None means not yet, so a woken task asks again rather than trusting the
wake. Err is the handshake's own failure (a refused or unreachable peer)
and leaves the socket for the caller to close.
#netTryRecv
netTryRecv : Socket h -> Int -> <Net h> Result String (Option (Array Int))netRecv that returns None instead of blocking. Some [] is end of
stream.
#netTryRecvBytes
netTryRecvBytes : Socket h -> Int -> <Net h> Result String (Option ByteBlock)netTryRecv delivering the chunk as a packed block, one byte per byte
rather than one boxed word per byte. Some an empty block is end of
stream. The block is allocated for this call alone and reaches the caller
with no other reference to it.
#netTrySend
netTrySend : Socket h -> Array Int -> <Net h> Result String (Option Int)netSend that returns None instead of blocking. Some n is the count
written, which may be short.
#netTrySendFrom
netTrySendFrom : Socket h -> Array Int -> Int -> <Net h> Result String (Option Int)netTrySend starting at the given offset into the array, sending at most 64 KiB
per call, so a loop over a large payload pays only for the bytes it sends.
#netSendBytesFrom
netSendBytesFrom : Socket h -> ByteBlock -> Int -> Int -> <Net h> Result String IntSends the bytes of a block in the window between two indices, from the first index up to but not including the second, at most 64 KiB per call. The result is the number of bytes written, which may be fewer than asked for.
A window outside the block, where the first index is negative, the second
is less than the first, or the second is past the block's length, is
Err. Unlike netSendFrom, which clamps its offset, the window is not
clamped: a window outside the block is a caller's mistake, and clamping
would hide it.
#netTrySendBytesFrom
netTrySendBytesFrom : Socket h -> ByteBlock -> Int -> Int -> <Net h> Result String (Option Int)netSendBytesFrom that returns None instead of blocking. Some n is
the count written, which may be short. A window outside the block is Err,
as for netSendBytesFrom.
#Time
#wallTimeSec
wallTimeSec : Unit -> <Clock> FloatThe wall-clock time in seconds since the epoch.
#monotonicSec
monotonicSec : Unit -> <Clock> FloatA monotonic clock reading in seconds, for measuring intervals.
#sleepMs
sleepMs : Int -> <Clock> UnitPauses the program for a number of milliseconds.
#allocBytes
allocBytes : Unit -> <IO> FloatThe total number of bytes the program has allocated.
#Random numbers
#randomInt
randomInt : Int -> Int -> <Rand> IntA random integer between its two arguments, inclusive.
#randomBool
randomBool : Unit -> <Rand> BoolA random boolean.
#randomFloat
randomFloat : Unit -> <Rand> FloatA random float.
#randomChar
randomChar : Unit -> <Rand> CharA random character.
#setSeed
setSeed : Int -> <Rand> UnitSeeds the random number generator, making the following draws repeatable.
#osEntropyBytes
osEntropyBytes : Int -> <Rand> Array IntExactly the given number of bytes from the operating system's entropy
source.
Independent of setSeed. Panics for a negative length or when the source
fails.
#Hashing
#hashInt
hashInt : Int -> IntThe hash of an integer.
#hashFloat
hashFloat : Float -> IntThe hash of a float.
#hashString
hashString : String -> IntThe hash of a string.
#hashChar
hashChar : Char -> IntThe hash of a character.
#hashBool
hashBool : Bool -> IntThe hash of a boolean.
#Numbers
#pi
pi : FloatThe constant π.
#e
e : FloatThe constant e, the base of natural logarithms.
#intMinBound
intMinBound : IntThe smallest Int.
#intMaxBound
intMaxBound : IntThe largest Int.
#charMinBound
charMinBound : CharThe smallest Char, U+0000.
#charMaxBound
charMaxBound : CharThe largest Char, U+10FFFF.
#intToFloat
intToFloat : Int -> FloatAn integer as a float.
#floatToInt
floatToInt : Float -> IntA float truncated towards zero as an integer.
#floatRem
floatRem : Float -> Float -> FloatThe remainder of a / b with the sign of a, as the % operator
computes it for floats.
#bitAnd
bitAnd : Int -> Int -> IntBitwise and.
#bitOr
bitOr : Int -> Int -> IntBitwise or.
#bitXor
bitXor : Int -> Int -> IntBitwise exclusive or.
#shiftLeft
shiftLeft : Int -> Int -> IntThe first argument shifted left by the second, in bits. The bits shifted
past bit 62 are discarded, so bit 62 becomes the sign, and an amount of 63
or more gives 0. A negative amount panics.
#shiftRight
shiftRight : Int -> Int -> IntThe first argument shifted right by the second, in bits, each vacated bit
a copy of the sign. An amount of 63 or more gives 0, or -1 for a
negative value. A negative amount panics.
#bitNot
bitNot : Int -> IntBitwise complement.
#Math
#sqrt
sqrt : Float -> FloatThe square root.
#cbrt
cbrt : Float -> FloatThe cube root.
#exp
exp : Float -> Floate raised to the given power.
#log
log : Float -> FloatThe natural logarithm.
#log2
log2 : Float -> FloatThe base-2 logarithm.
#log10
log10 : Float -> FloatThe base-10 logarithm.
#sin
sin : Float -> FloatThe sine of an angle in radians.
#cos
cos : Float -> FloatThe cosine of an angle in radians.
#tan
tan : Float -> FloatThe tangent of an angle in radians.
#asin
asin : Float -> FloatThe arc sine, in radians.
#acos
acos : Float -> FloatThe arc cosine, in radians.
#atan
atan : Float -> FloatThe arc tangent, in radians.
#sinh
sinh : Float -> FloatThe hyperbolic sine.
#cosh
cosh : Float -> FloatThe hyperbolic cosine.
#tanh
tanh : Float -> FloatThe hyperbolic tangent.
#floor
floor : Float -> FloatThe largest integral value not greater than the argument.
#ceil
ceil : Float -> FloatThe smallest integral value not less than the argument.
#round
round : Float -> FloatThe nearest integral value, with halves rounded away from zero.
#trunc
trunc : Float -> FloatThe integral part of the argument, rounding towards zero.
#pow
pow : Float -> Float -> FloatThe first argument raised to the power of the second.
#atan2
atan2 : Float -> Float -> FloatThe angle in radians of the point (x, y), given as atan2 y x.
#hypot
hypot : Float -> Float -> FloatThe length of the hypotenuse, sqrt (x * x + y * y), without
intermediate overflow.
#intBitsToFloat
intBitsToFloat : Int -> FloatThe float whose IEEE 754 bit pattern is the given integer.
#floatToBytes64
floatToBytes64 : Float -> Array IntA float as its eight big-endian IEEE 754 bytes, 0 to 255 each.
#Rendering
#intToString
intToString : Int -> StringAn integer in decimal.
#floatToString
floatToString : Float -> StringA float in decimal.
#Arrays
#arrayLength
arrayLength : Array a -> IntThe number of elements.
#arrayMake
arrayMake : Int -> a -> Array aA new array of the given length, every element a copy of the value.
#arrayMakeWith
arrayMakeWith : Int -> (Int -> <e> a) -> <e> Array aA new array of the given length whose element at each index is the function applied to that index.
#arrayCopy
arrayCopy : Array a -> Array aA new array with the same elements.
#arrayFromList
arrayFromList : List a -> Array aA new array holding the elements of a list.
#Byte blocks
#byteBlockLength
byteBlockLength : ByteBlock -> IntThe number of bytes.
#byteBlockToIntArray
byteBlockToIntArray : ByteBlock -> Array IntA new array holding each byte as an Int in the range 0 to 255.
#byteBlockFromString
byteBlockFromString : String -> ByteBlockA new block holding the UTF-8 encoding of a string.
#Strings
#stringToChars
stringToChars : String -> Array CharThe codepoints of a string.
#stringFromChars
stringFromChars : Array Char -> StringA string built from an array of characters.
#stringToUtf8Bytes
stringToUtf8Bytes : String -> Array IntThe UTF-8 encoding of a string, one byte (0 to 255) per element.
#stringFromUtf8Bytes
stringFromUtf8Bytes : Array Int -> StringThe string encoded by an array of UTF-8 bytes. Only the low eight bits of each element are used, and each ill-formed sequence becomes one U+FFFD per maximal subpart.
#charToStr
charToStr : Char -> StringA one-character string.
#charCode
charCode : Char -> IntA character's codepoint.
#charFromCode
charFromCode : Int -> Option CharThe character with a codepoint, or None when the codepoint is not a
Unicode scalar value.
#stringLength
stringLength : String -> IntThe number of codepoints in a string.
#stringSlice
stringSlice : Int -> Int -> String -> StringThe characters at positions [lo, hi), clamped to the string.
#stringConcat
stringConcat : List String -> StringThe strings joined end to end.
#stringIndexOf
stringIndexOf : String -> String -> Option IntThe position of the first occurrence of the first string in the second,
or None.
#stringCompare
stringCompare : String -> String -> OrderingThe ordering of two strings, by codepoint.
#stringToFloat
stringToFloat : String -> Option FloatThe float written in a string, or None.
#Characters
#charIsAlpha
charIsAlpha : Char -> BoolWhether a character is an ASCII letter.
#charIsSpace
charIsSpace : Char -> BoolWhether a character is ASCII whitespace.
#charIsUpper
charIsUpper : Char -> BoolWhether a character is an ASCII uppercase letter.
#charIsLower
charIsLower : Char -> BoolWhether a character is an ASCII lowercase letter.
#charIsPunct
charIsPunct : Char -> BoolWhether a character is ASCII punctuation.
#charToUpper
charToUpper : Char -> CharAn ASCII letter in uppercase. Any other character is unchanged.
#charToLower
charToLower : Char -> CharAn ASCII letter in lowercase. Any other character is unchanged.
#stringToUpper
stringToUpper : String -> StringA string with every ASCII letter in uppercase.
#stringToLower
stringToLower : String -> StringA string with every ASCII letter in lowercase.