The osen reference

Every name the language binds, in alphabetical order: what every host has. Each entry gives what the name takes and what it answers, in the form (arguments) -> answer, and an example with what it answered. A sequence is a bundle (1, 2, 3) or a list [1, 2, 3], and a name that holds one works wherever a literal does. What a host adds of its own – sockets, files, a console, a patch – is on that host’s page.

For how any of this is called – what (), {}, [] and a trailing colon do – see Calling C from osen.

The names

/o/abs

(x) -> x without its sign

(-5) /o/abs
# -> : 5

/o/add

(a, b) -> their sum

Two ints or two floats; a mixed pair is refused as the wrong type of item.

(1, 2) /o/add
# -> : 3

/o/all

(sequence, predicate) -> 1 if the predicate answers non-zero for every item, else 0

((1, 2, 3), ({ (/x, 0) /o/gt }, ["/x"]) /o/defn) /o/all
# -> : 1

/o/and

(a, b) -> 1 if both ints are non-zero, else 0

(1, 0) /o/and
# -> : 0

/o/any

(sequence, predicate) -> 1 if the predicate answers non-zero for any item, else 0

((1, 2, 3), ({ (/x, 2) /o/gt }, ["/x"]) /o/defn) /o/any
# -> : 1

/o/apply

(function, arguments) -> the function's result

A pointer is called on the spot; a function written in osen takes the frame road through /o/execlambdaapp. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/assign

(bundle, value, "/address") -> a copy of the bundle with the value bound at that address

Replaces the element already at the address, or appends one. The bundle may be a literal or a name read.

((/y : 42), 99, "/y") /o/assign
# -> ( /y : 99 )
((/y : 42), 99, "/z") /o/assign
# -> ( /y : 42, /z : 99 )

/o/assign/toreg

("/_r", value, "/address") -> nothing; binds the value at that address in that register

The only way for a program to write into a register other than its own environment.

("/_x", 1, "/y") /o/assign/toreg, /y
# -> : [] : 1

/o/backtrace

(machine) -> a list: what each open frame still had to do, then what the machine itself was about to do

After /x : 10, (/x, /z) /o/add halts, with the machine the host held as /m:

(/m) /o/backtrace -> : [ { : "/!/o/finalize/toplevelexec", : "/!/drop" }, { : "/!/os/F" }, { : "/!/os/E", : "", : "/!/os/C2", : "/o/add" } ]

/o/bind

("/name", value) -> nothing; the name bound in the environment

What a statement /name : value becomes. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/bound

("/name") -> 1 if the name exists and carries a value, else 0

("/o/add") /o/bound
# -> : 1

/o/bundleitem/tobundleelem

(x) -> x as a bundle element if it arrived as a bundle item; anything else unchanged

A bundle read through a name arrives as one item of a message; this is the normalisation every sequence verb does, exposed.

(10) /o/bundleitem/tobundleelem
# -> : 10

/o/butlast

(sequence) -> the sequence without its last item

((1, 2, 3)) /o/butlast
# -> ( : 1, : 2 )

/o/concat/blobs

(blob, blob) -> one blob, the second's bytes after the first's

((5) /o/toblob/fromitem, (6) /o/toblob/fromitem) /o/concat/blobs
# -> : "/,/b/\x00\x00\x00\x05\x00\x00\x00\x06"

/o/concat/elems

(a, b) -> one sequence: a's items followed by b's

Two lists make a list; two bundles make a bundle.

([1, 2], [3, 4]) /o/concat/elems
# -> : [ 1, 2, 3, 4 ]
((/a : 1), (/b : 2)) /o/concat/elems
# -> ( /a : 1, /b : 2 )

/o/concat/strings

(string, string) -> one string, the second after the first

("ab", "cd") /o/concat/strings
# -> : "abcd"

/o/count/elems

(x) -> 1

It counts the elements of the stack beneath it, which is what libose’s COUNTELEMS does, and once the argument bundle is unpacked that is always one. /o/length is the verb that counts what a sequence holds.

((1, 2, 3)) /o/count/elems
# -> : 1

/o/count/items

(sequence) -> how many items it holds; the same function as /o/length

((/a : 1, /b : 2)) /o/count/items
# -> : 2

/o/db

(machine) -> one bundle showing it: /frames, /aboutto, /stack, /env, /pending, and /andyoucan

The whole of a halted machine at once; the prompt prints it like any other value, and the next line is ordinary osen against the same machine.

(() /o/machine/new) /o/db

/o/decat/blob/fromstart

(blob, n) -> [its first n bytes, the rest]

((5) /o/toblob/fromitem, 1) /o/decat/blob/fromstart
# -> : [ "/,/b/\x00", "/,/b/\x00\x00\x05" ]

/o/decat/string/fromstart

(string, n) -> [its first n characters, the rest]

("hello", 2) /o/decat/string/fromstart
# -> : [ "he", "llo" ]

/o/defn

({ body }, ["/params"...]) -> a function

The body is a brace bundle and the parameters a list of names; calling the function binds the arguments to those names and runs the body. The named form ( /body : { }, /args : [ ] ) is the same call. The optional named slots are /name, what the function calls itself; /captured, the names to close over now; and /ambient.

/f : ({ (/a, /b) /o/add }, ["/a", "/b"]) /o/defn, (1, 2) /f
# -> : 3
/y : 10, /f : ({ (/x, /y) /o/add }, ["/x"], /captured : ["/y"]) /o/defn, (5) /f
# -> : 15

/o/div

(a, b) -> a divided by b

Two ints divide as ints.

(7, 2) /o/div
# -> : 3

/o/drain

() -> nothing; what /o/out staged in the output register moves to the input and runs

The o.se prompt drains after every line by itself.

() /o/drain
# -> ()

/o/each

(sequence, function) -> 0, after calling the function on each item for its effect

((1, 2, 3), ({ (/x) /o/println }, ["/x"]) /o/defn) /o/each
# -> : 1 : 2 : 3 : 0

/o/eql

(a, b) -> 1 if equal, else 0

Ints, floats, strings, lists and bundles compare; an int and a float with the same value are not equal.

(1, 1) /o/eql
# -> : 1

/o/eval

("source") -> what the host's evaluator makes of it

The host decides what evaluating is: a prompt hands the string to its own read-eval-print, a host without one to its evaluator. In the browser host (“(1, 2) /o/add”) /o/eval answers 3.

("(1, 2) /o/add") /o/eval

/o/exec

(bundle) -> a bundle of what its elements produced

Executing a bundle produces a bundle; an empty one stays empty. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/exec/blob

(blob) -> a bundle of what the bundle inside the blob produced

An eager bracket the parser left encoded, converted and executed in one step. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/exec/toplevel

(bundle) -> its elements run as a line at the top level

An evaluator step, the way the prompt runs a parsed line; a program has no reason to call it.

/o/exec2

(bundle) -> its elements run, by the instruction language's exec2

An evaluator step; a program has no reason to call it.

/o/execbranch

(branch) -> the branch running, as /o/if runs one

The same execution as /o/exec with /o/finalize/branch at the end. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/execlambdaapp

(function, arguments) -> the body running in a new frame

Opens the frame a function call runs in. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/exists

("/name") -> 1 if a message with that address is anywhere the lookup searches, else 0

Present with no value still counts; /o/bound asks for the value too.

("/o/add") /o/exists
# -> : 1
("/nope") /o/exists
# -> : 0

/o/false

a value -> false, the F type

answers 1: the logical verbs read ints, not these.

(/o/false) /o/typeof1
# -> : "/-/F"

/o/fill

({ body }) -> the body with each /%/name replaced by that name's value now

What a brace bundle does to its /%/ holes when it is written; this is the same fill as a verb, for a body held in a value.

/x : 5, /t : ({ (/%/x, 1) /o/add }) /o/fill, /x : 100, ({ 0 }, /t, 1) /o/if
# -> : 6

/o/fill/all

({ body }) -> the body with every free name replaced by its value now

What %{ } does when it is written: every name that resolves is filled, except the vocabulary under /o/ and /prim/, which the receiver has. As a verb on a body already written with { } it fills in the browser host and not at the o.se prompt, which answers 101 for the second line below.

/x : 5, /t : %{ (/x, 1) /o/add }, /x : 100, ({ 0 }, /t, 1) /o/if
# -> : 6
/x : 5, /t : ({ (/x, 1) /o/add }) /o/fill/all, /x : 100, ({ 0 }, /t, 1) /o/if

/o/filter

(sequence, predicate) -> a list of the items the predicate answers non-zero for

The predicate is a function of one argument.

((1, 2, 3, 4), ({ (/x, 2) /o/gt }, ["/x"]) /o/defn) /o/filter
# -> : [ 3, 4 ]

/o/finalize/branch

(a branch that has run) -> its values, unwrapped, on the caller's stack

A branch is part of the expression around it, so what it produced comes back as values rather than sealed in a bundle. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/finalize/elem

(an element that has been evaluated) -> its value, bound if it was named

A statement /x : 5 binds after this step; a bare value stays on the stack. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/finalize/exec

(a frame that has run) -> its results, the frame closed

Separates what the body produced from the environment beneath it and restores the caller’s. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/finalize/execlambdaapp

(a function body that has run) -> its last value, the frame closed

A function answers with one value: the last the body produced, or nothing for an empty body. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/finalize/toplevelexec

(a line that has run) -> its values, ready for the prompt to print

An evaluator step, emitted by the parser; a program has no reason to call it.

/o/find

(sequence, predicate) -> the first item the predicate answers non-zero for

((1, 2, 3, 4), ({ (/x, 2) /o/gt }, ["/x"]) /o/defn) /o/find
# -> : 3

/o/first

(sequence) -> its first item

A sequence is a bundle, (1, 2, 3), or a list, [1, 2, 3]; a name read works too.

((1, 2, 3)) /o/first
# -> : 1

/o/fold

(sequence, init, fn) -> the last accumulator

fn is called as (acc, item) fn for each item, and its answer is the next accumulator; init is the first.

((1, 2, 3), 10, /o/add) /o/fold
# -> : 16

/o/foldrest

(a fold in progress) -> its next round

An evaluator step: /o/fold schedules it after each call of the step function. A program has no reason to call it.

/o/format

(x) -> x, and its printed form as a string

The form the prompt prints, one line, without a newline.

(5) /o/format
# -> : [ 5, ": 5" ]

/o/formatln

(x) -> x, and its printed form as a string ending in a newline

((1, 2, 3)) /o/formatln
# -> : [ ( : 1, : 2, : 3 ), "( : 1, : 2, : 3 ) " ]

/o/frame

(machine, k) -> frame k: what it saved, in the order /_i, /_e, /_s, /_c, omitting registers that were empty

After a halt, with the machine the host held as /m:

(/m, 0) /o/frame -> ( ( : "/!/o/finalize/toplevelexec", : "/!/drop" ) )

/o/frames

(machine) -> how many frames it has open

(() /o/machine/new) /o/frames
# -> : 0

/o/funcall

(function, arguments) -> the function's result, from a quoted call

What a quoted call in a callback list resolves to. An evaluator step, emitted by the parser; a program has no reason to call it.

/o/gather

(bundle, "/address") -> a list of two bundles: the elements whose address matches, and the rest

((/a : 1, /b : 2), "/a") /o/gather
# -> : [ ( /a : 1 ), ( /b : 2 ) ]

/o/get

(bundle, (step, ...)) -> the value at the end of the path

Each step is an address, looked up, or an index, counted from 0.

((/a : (/b : 5)), ("/a", "/b")) /o/get
# -> : 5
((1, 2, 3), (1)) /o/get
# -> : 2

/o/get/addresses

(bundle) -> a list of its elements' addresses, in order

((/a : 1, /b : 2)) /o/get/addresses
# -> : [ "/a", "/b" ]

/o/gt

(a, b) -> 1 if a is greater than b, else 0

(1, 2) /o/gt
# -> : 0

/o/gte

(a, b) -> 1 if a is at least b, else 0

(2, 2) /o/gte
# -> : 1

/o/if

({ iffalse }, { iftrue }, condition) -> what the chosen branch produced

The branches are brace bundles and the condition an int, 0 choosing the first. What the branch left comes back as values, not wrapped in a bundle.

({ 0 }, { 1 }, 1) /o/if
# -> : 1

/o/infinitum

a value -> infinitum, the I type

(/o/infinitum) /o/typeof1
# -> : "/-/I"

/o/insert/fromend

(target, item, "/key") -> the same, reading the target as descending

(((/due : 30), (/due : 10)), (/due : 20), "/due") /o/insert/fromend
# -> ( ( /due : 30 ), ( /due : 20 ), ( /due : 10 ) )

/o/insert/fromstart

(target, item, "/key") -> a copy of the target with the item placed by the number at /key, reading the target as ascending

Every element of the target carries a number at /key. Equal keys keep their arrival order. An item with no such key, or a non-number there, is refused.

(((/due : 10), (/due : 30)), (/due : 20), "/due") /o/insert/fromstart
# -> ( ( /due : 10 ), ( /due : 20 ), ( /due : 30 ) )

/o/inspect

(x) -> its printed form as a string, with nothing collapsed

The prompt’s printer with the collapse off, answering a string a program can hold, compare or send.

((1, 2, 3)) /o/inspect
# -> : "( : 1, : 2, : 3 )"

/o/is/closure

(value) -> 1 if it is a function carrying captured bindings, else 0

/y : 10, /f : ({ (/x, /y) /o/add }, ["/x"], /captured : ["/y"]) /o/defn, (/f) /o/is/closure
# -> : 1

/o/is/lambda

(value) -> 1 if it is a function, else 0

A function is a bundle declaring /_i and /_p, as /o/defn makes one.

(/o/add) /o/is/lambda
# -> : 1

/o/is/machine

(value) -> 1 if it is a machine, else 0

A machine is a bundle declaring the five registers, whatever their order.

(() /o/machine/new) /o/is/machine
# -> : 1

/o/is/thunk

(value) -> 1 if it is a thunk, else 0

A thunk is a bundle declaring /_i and nothing else: a body with no parameters. A brace bundle held in a name is a blob, not a thunk, and answers 0.

((/_i : { 1 })) /o/is/thunk
# -> : 1

/o/is/type/string

(x) -> x, and 1 if it is a string, else 0

("a") /o/is/type/string
# -> : [ "a", 1 ]

/o/last

(sequence) -> its last item

((1, 2, 3)) /o/last
# -> : 3

/o/length

(sequence) -> how many items it holds

A bundle’s elements or a list’s items; a literal and a name read count the same. /o/count/items is the same function.

((1, 2, 3)) /o/length
# -> : 3
/x : (1, 2, 3), (/x) /o/length
# -> : 3

/o/length/item

(string) -> how many characters it has

("hello") /o/length/item
# -> : 5

/o/listen

(port, handler) -> nothing; the handler is called with each bundle that arrives on the port

The handler is a function of one argument and receives the arrival as data, not run. Needs a host with sockets.

/arrived : ({ ((/b) /o/length) /o/println }, ["/b"]) /o/defn, (9999, /arrived) /o/listen

/o/lookup

(bundle, "/address") -> the message at that address, or the empty message

The bundle may be a literal or a name read; a name that is not there answers the empty message rather than raising.

((/a : 1, /b : 2), "/b") /o/lookup
# -> : 2
((/a : 1, /b : 2), "/c") /o/lookup
# -> : []

/o/lookup/inenv

("/name") -> the message the name is bound to, searched the way a name read is

Raises if the name is not bound; /o/exists asks without raising.

/x : 3, ("/x") /o/lookup/inenv
# -> : 3

/o/lt

(a, b) -> 1 if a is less than b, else 0

Numbers only; two strings are refused as the wrong type of item.

(1, 2) /o/lt
# -> : 1

/o/lte

(a, b) -> 1 if a is at most b, else 0

(2, 2) /o/lte
# -> : 1

/o/machine/bind

(machine, value, "/name") -> the machine with the name bound in every one of its environments

Unconditional: a frame that already had the name gets the new value, so use it for a name that is unbound everywhere. After the line the machine as /m:

/x : 10, (/x, /z) /o/add, (/z, 100) /o/add halts and the host holds
(((/m, 5, "/z") /o/machine/bind, 5) /o/machine/store/value, ("/_s")) /o/get -> : ( : 15, : 105 )

/o/machine/new

() -> an empty machine, as a value

Five empty registers in a bundle, a value like any other: put things in it with /o/put, send it, or hand it to a host that runs machines.

(() /o/machine/new) /o/is/machine
# -> : 1

/o/make/register

(size, "/_r") -> nothing; a register of that many bytes made under that name

A name already in use is refused.

(1024, "/_z") /o/make/register
# -> : []

/o/map

(sequence, function) -> a list of the function's answers, one per item

Addresses are not kept: a bundle of named elements maps to a plain list.

((1, 2, 3), ({ (/x, 10) /o/mul }, ["/x"]) /o/defn) /o/map
# -> : [ 10, 20, 30 ]

/o/match

("/address", "/pattern") -> [the address, the pattern, 1 if the pattern matches the whole address, else 0]

("/a/b", "/a/*") /o/match
# -> : [ "/a/b", "/a/*", 0 ]

/o/max

(a, b) -> the larger

(1, 2) /o/max
# -> : 2

/o/min

(a, b) -> the smaller

(1, 2) /o/min
# -> : 1

/o/mod

(a, b) -> the remainder of a divided by b

(7, 3) /o/mod
# -> : 1

/o/mul

(a, b) -> their product

(3, 4) /o/mul
# -> : 12

/o/neg

(x) -> x with its sign flipped

(5) /o/neg
# -> : -5

/o/neq

(a, b) -> 1 if they differ, else 0

(1, 2) /o/neq
# -> : 1

/o/nfill

(x, n) -> a list of n copies of x

(7, 3) /o/nfill
# -> : [ 7, 7, 7 ]

/o/nil

a value -> nil, the N type

(/o/nil) /o/typeof1
# -> : "/-/N"

/o/not

(x) -> 1 if the int is 0, else 0

(0) /o/not
# -> : 1

/o/nth

(sequence, n) -> item n, counting from 0

((10, 20, 30), 1) /o/nth
# -> : 20

/o/or

(a, b) -> 1 if either int is non-zero, else 0

(1, 0) /o/or
# -> : 1

/o/out

("/channel", value...) -> nothing; appends /channel : value... to the output register

The register is /_o, a bundle of messages addressed by channel; emitting appends, so repeated channels keep their order. What the host does with a channel is its own: at the o.se prompt the register is drained into the input, so (“/println”, 1) /o/out prints 1. The register must exist, and one is made with (65536, “/_o”) /o/make/register.

("/println", 1) /o/out

/o/parse

("source") -> [the program the source parses to, 0]

The program is a bundle of what the parser emitted, not yet run. A syntax error raises instead.

("(1, 2) /o/add") /o/parse
# -> : [ ( : <thunk> ), 0 ]

/o/pmatch

("/address", "/pattern") -> [what is left of the address after the match, the pattern, 1 if the address was fully matched, 1 if the pattern was]

A partial match: the pattern may match a prefix of the address.

("/a/b/c", "/a") /o/pmatch
# -> : [ "/b/c", "/a", 0, 1 ]

/o/pop

(sequence) -> [the sequence without its last item, that item]

((1, 2, 3)) /o/pop
# -> : [ ( : 1, : 2 ), 3 ]

/o/pop/all/drop/bundle

(sequence) -> a bundle of its items, last first

((1, 2, 3)) /o/pop/all/drop/bundle
# -> ( : 3, : 2, : 1 )

/o/pow

(a, b) -> a to the power b

(2, 10) /o/pow
# -> : 1024

/o/print

(x) -> x, printed without a newline

Prints the last argument in the form the prompt uses.

("hi") /o/print
# -> : "hi"

/o/println

(x) -> x, printed with a newline

("hi") /o/println
# -> : "hi"

/o/push

(sequence, x) -> the sequence with x appended

((1, 2), 3) /o/push
# -> ( : 1, : 2, : 3 )

/o/put

(bundle, value, (step, ...)) -> a copy of the bundle with the value at the end of the path

The write side of /o/get; the same steps.

((/a : (/b : 5)), 9, ("/a", "/b")) /o/put
# -> ( /a : { /b : 9 } )
((1, 2, 3), 9, (1)) /o/put
# -> ( : 1, : 9, : 3 )

/o/range

(end), (start, end) or (start, end, step) -> the list of ints from start up to but not including end

Start is 0 and step is 1 when not given; a negative step counts down.

(3) /o/range
# -> : [ 0, 1, 2 ]
(2, 5) /o/range
# -> : [ 2, 3, 4 ]
(0, 10, 3) /o/range
# -> : [ 0, 3, 6, 9 ]

/o/register/flags

("/_r") -> a bundle of that register's flags, each 0 or 1

("/_x") /o/register/flags
# -> ( /flag/local : 1, /flag/temp : 0 )

/o/register/flags/set

("/_r", (/flag/name : 0 or 1, ...)) -> how many of the flag names it understood

An unknown flag name is ignored, not an error, so a program can tell a host that predates the flag from one that set it.

(1024, "/_z") /o/make/register, ("/_z", (/flag/temp : 1)) /o/register/flags/set
# -> : [] : 1

/o/rest

(sequence) -> the sequence without its first item

A bundle stays a bundle and a list a list.

((1, 2, 3)) /o/rest
# -> ( : 2, : 3 )

/o/reverse

(sequence) -> the sequence with its items in the opposite order

((1, 2, 3)) /o/reverse
# -> ( : 3, : 2, : 1 )

/o/route

(bundle, "/address") -> a bundle of two: the matching elements with the matched part taken off their addresses, then the rest

((/a : 1, /b : 2), "/a") /o/route
# -> ( ( : 1 ), ( /b : 2 ) )

/o/select

(bundle, ["/address", ...]) -> a bundle of one bundle per address, last address first, and the unmatched rest at the end

((/a : 1, /b : 2, /c : 3), ["/a", "/c"]) /o/select
# -> ( ( /c : 3 ), ( /a : 1 ), ( /b : 2 ) )

/o/send

(arguments...) -> whatever the host's send answers

Late bound: a host without a send of its own answers through its unbound-name handler.

/o/set/nth

(sequence, new, n) -> a copy of the sequence with item n replaced by new

Counts from 0. The write side of /o/nth.

((10, 20, 30), 99, 1) /o/set/nth
# -> ( : 10, : 99, : 30 )

/o/sort

(list) -> the list with its items in ascending order

Ints, floats or strings; a bundle of elements comes back as it was.

([3, 1, 2]) /o/sort
# -> : [ 1, 2, 3 ]

/o/sortidxs

(list) -> the positions its items would be taken from to sort it

([3, 1, 2]) /o/sortidxs
# -> : [ 1, 2, 0 ]

/o/split/string/fromend

(string, separator) -> [the tail from the last separator, the head before it, the separator]

A separator that does not occur answers [the string, the separator].

("a.b.c", ".") /o/split/string/fromend
# -> : [ ".c", "a.b", "." ]

/o/sub

(a, b) -> a minus b

(5, 2) /o/sub
# -> : 3

/o/toblob/fromelem

(element) -> the element's bytes as a blob

A bundle so encoded prints in braces; /o/toelem/fromblob decodes it.

((1, 2)) /o/toblob/fromelem
# -> : { : 1, : 2 }

/o/toblob/fromitem

(item) -> the item's bytes as a blob

(5) /o/toblob/fromitem
# -> : "/,/b/\x00\x00\x00\x05"

/o/todouble

(number) -> the same number as a double

(3) /o/todouble
# -> : 3.000000

/o/toelem/fromblob

(blob) -> the bundle element the blob's bytes encode

The inverse of /o/toblob/fromelem.

(((1, 2)) /o/toblob/fromelem) /o/toelem/fromblob
# -> ( : 1, : 2 )

/o/tofloat

(number) -> the same number as a float

(3) /o/tofloat
# -> : 3.0

/o/toint16

(number) -> the same number as an int16

The prompt has no printer for this type; /o/typeof1 shows what came back.

((300) /o/toint16) /o/typeof1
# -> : "/-/u"

/o/toint32

(number or "digits") -> the same as an int32

A float is truncated.

(3.7) /o/toint32
# -> : 3

/o/toint64

(number) -> the same number as an int64

((3) /o/toint64) /o/typeof1
# -> : "/-/h"

/o/toint8

(number) -> the same number as an int8

((300) /o/toint8) /o/typeof1
# -> : "/-/c"

/o/tostring

(x) -> its text as a string

(42) /o/tostring
# -> : "42"

/o/tosymbol

(x) -> its text as a symbol

(42) /o/tosymbol
# -> : "/,/S/42"

/o/totimetag

(int) -> that many seconds from 1900, as a timetag

(42) /o/totimetag
# -> : "/,/t/1900-01-01T00:00:42.000000Z"

/o/touint16

(number) -> the same number as a uint16

((3) /o/touint16) /o/typeof1
# -> : "/-/U"

/o/touint32

(number) -> the same number as a uint32

((3) /o/touint32) /o/typeof1
# -> : "/-/k"

/o/touint64

(number) -> the same number as a uint64

((3) /o/touint64) /o/typeof1
# -> : "/-/H"

/o/touint8

(number) -> the same number as a uint8

((3) /o/touint8) /o/typeof1
# -> : "/-/C"

/o/true

a value -> true, the T type

Not a function: reading the name gives the value.

(/o/true) /o/typeof1
# -> : "/-/T"

/o/typeof0

(x) -> "/-" for a message, "/|" for a bundle

((1, 2)) /o/typeof0
# -> : "/|"

/o/typeof1

(x) -> its type one level down: the element's kind, then its items' typetags

(1) /o/typeof1
# -> : "/-/i"
(["a", 1, 2.5]) /o/typeof1
# -> : "/-/sif"

/o/typeof2

(x) -> its type to full depth

(("a", 1, 2.5)) /o/typeof2
# -> : "/|/-/s/-/i/-/f"

/o/typetag/set

(item, code) -> the item with its typetag replaced by the character code; the bytes stay

A reinterpretation, not a conversion: 105 is ‘i’, and 1.5’s bits read as an int.

(1.5, 105) /o/typetag/set
# -> : 1069547520

/o/unpack/drop

(bundle) -> its elements, each on the stack by itself

((1, 2, 3)) /o/unpack/drop
# -> : [ 1, 2, 3 ]

/o/unwrap

two names on the stack, an instruction and the /o/ name to bind -> nothing; the /o/ name bound as the instruction with the argument bundle unpacked first

The bootstrap the generated wrappers are written with, at the instruction level, as the line below binds /o/eval.

/,/s//!/eval /,/s//o/eval /!/o/unwrap

/o/whence

("/name") -> the register the name resolves in, or "" if nowhere

The name is a string and is not looked up, so asking never moves a program elsewhere.

("/o/add") /o/whence
# -> : "/_x"

/o/zipwith

((sequence, ...), fn) -> a list of fn applied across the sequences, item by item

The sequences travel as one bundle; fn takes one argument per sequence.

(((1, 2, 3), (4, 5, 6)), /o/add) /o/zipwith
# -> : [ 5, 7, 9 ]

/o/zipwithrest

(a zipwith in progress) -> its next round

An evaluator step: /o/zipwith schedules it between calls of the function it is applying. A program has no reason to call it.

Implementation — for embedders and module authors

Implementation

osen-stdlib.tsv says a name exists and where its binding comes from. This says what it is built out of.

Where a C body makes exactly one libose call, that call’s denotational spec is its meaning – the last column names the spec block in libose’s ose_stackops.c; build libose’s docs with make doc and read that function’s entry. Where it makes several, the meaning is the composition and no single spec covers it. A wrapper written in osen or ose is listed by the instructions it runs.

name defined in implemented as spec
/o/backtrace higher.osen (higher.osen)  
/o/db higher.osen (higher.osen)  
/o/frame higher.osen (higher.osen)  
/o/frames higher.osen (higher.osen)  
/o/machine/bind higher.osen (higher.osen)  
/o/set/nth C:registered ose_peekType, ose_unpackDrop, ose_peekType, ose_peekMessageArgType, ose_popInt32, ose_drop, ose_popInt32, ose_swap, ose_swap, ose_getLastBundleElemOffset, ose_getBundleElemCount, ose_readInt32, ose_getBundleElemType, ose_readInt32, ose_readInt32, ose_readInt32, ose_copyElemAtOffset, ose_copyElemAtOffset, ose_pushInt32, ose_bundleFromTop, ose_swap, ose_drop, ose_swap, ose_drop  
/o/abs C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnunop{ABS}
/o/add C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{ADD}
/o/all higher.osen (higher.osen)  
/o/and C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{AND}
/o/any higher.osen (higher.osen)  
/o/apply C:registered (C:registered)  
/o/assign C:OSEN_PUSHFN+prelude.ose /!/unpack/drop /!/assign  
/o/assign/toreg C:registered ose_peekType, ose_unpackDrop, ose_peekType, ose_peekMessageArgType, ose_rot, ose_peekType, ose_peekMessageArgType, ose_getBundlePtr, ose_drop, ose_copyBundle, ose_rrot, ose_assign, ose_replaceBundle  
/o/bind C:registered (C:registered)  
/o/bound higher.osen (higher.osen)  
/o/bundleitem/tobundleelem host module (host module)  
/o/butlast C:OSEN_PUSHFN ose_pop, ose_nip, ose_pop, ose_drop  
/o/concat/blobs generated /!/unpack/drop /!/push /!/concat/blobs  
/o/concat/elems C:registered ose_peekType, ose_unpackDrop, ose_swap, ose_swap, ose_concatenateElems  
/o/concat/strings generated /!/unpack/drop /!/push /!/concat/strings  
/o/count/elems C:registered ose_peekType, ose_unpackDrop, ose_countElems, ose_nip  
/o/count/items C:registered ose_peekType, ose_unpackDrop, ose_countItems, ose_nip  
/o/decat/blob/fromstart generated /!/unpack/drop /!/decat/blob/fromstart  
/o/decat/string/fromstart generated /!/unpack/drop /!/decat/string/fromstart  
/o/defn C:OSEN_PUSHFN ose_getLastBundleElemOffset, ose_getBundleElemElemCount, ose_elemToBlob, ose_readInt32, ose_readInt32, ose_getBundleElemType, ose_readString, ose_getBundlePtr, ose_getBundleElemType, ose_pstrlen, ose_getBundlePtr, ose_getBundleElemType, ose_pstrlen, ose_pnbytes, ose_copyElemAtOffset, ose_copyElemAtOffset, ose_copyElemAtOffset, ose_copyElemAtOffset, ose_copyElemAtOffset, ose_pushInt32, ose_bundleFromTop, ose_elemToBlob, ose_getBundleElemType, ose_getBundlePtr, ose_readInt32, ose_copyElemAtOffset, ose_push, ose_elemToBlob, ose_push, ose_pushMessage, ose_readInt32, ose_getBundleElemType, ose_pushMessage, ose_push, ose_copyElemAtOffset, ose_pushInt32, ose_bundleFromTop, ose_nip, ose_elemToBlob  
/o/div C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{DIV}
/o/drain C:OSEN_PUSHFN ose_getContextMessageOffset, ose_enter, ose_getBundlePtr, ose_moveElem  
/o/each higher.osen (higher.osen)  
/o/eql C:OSEN_PUSHFN+prelude.ose /!/unpack/drop /!/eql  
/o/eval prelude.ose /!/unpack/drop /!/eval  
/o/exec C:registered (C:registered)  
/o/exec/blob C:registered (C:registered)  
/o/exec/toplevel generated /!/exec1 /!/drop /!/o/finalize/toplevelexec  
/o/exec2 generated /!/unpack/drop /!/exec2  
/o/execbranch C:registered (C:registered)  
/o/execlambdaapp C:registered (C:registered)  
/o/exists higher.osen (higher.osen)  
/o/false C:registered (C:registered)  
/o/filter higher.osen (higher.osen)  
/o/fill C:OSEN_PUSHFN (no libose call)  
/o/fill/all C:registered (no libose call)  
/o/finalize/branch C:registered (C:registered)  
/o/finalize/elem C:registered (C:registered)  
/o/finalize/exec C:registered (C:registered)  
/o/finalize/execlambdaapp C:registered (C:registered)  
/o/finalize/toplevelexec C:registered (C:registered)  
/o/find higher.osen (higher.osen)  
/o/first C:OSEN_PUSHFN ose_pop, ose_nip, ose_popAllDropBundle, ose_pop, ose_nip  
/o/fold C:OSEN_PUSHFN ose_peekType, ose_getBundleElemCount, ose_unpackDrop, ose_getBundleElemCount, ose_pop, ose_countItems, ose_pop, ose_reverse, ose_rot, ose_peekType, osevm_assignStackToEnv_impl, ose_reverse, ose_rot  
/o/foldrest C:registered (no libose call)  
/o/format host module (host module)  
/o/formatln host module (host module)  
/o/funcall C:registered (C:registered)  
/o/gather C:OSEN_PUSHFN ose_peekType, ose_unpackDrop, ose_peekType, ose_swap, ose_swap, ose_swap, ose_gather  
/o/get higher.osen (higher.osen)  
/o/get/addresses C:registered ose_peekType, ose_unpackDrop, ose_getAddresses, ose_nip  
/o/gt C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{GT}
/o/gte C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{GTE}
/o/if C:OSEN_PUSHFN ose_unpackDrop, ose_peekMessageArgType, osevm_toInt32, ose_pushInt32, ose_neq, ose_roll, ose_drop, ose_peekType, ose_peekMessageArgType, ose_setTypetag_impl, ose_blobToElem, ose_unpackDrop, ose_peekType, ose_countItems, ose_popInt32, ose_unpackDrop, ose_pushString, ose_swap  
/o/infinitum C:registered (C:registered)  
/o/insert/fromend C:registered (no libose call)  
/o/insert/fromstart C:registered (no libose call)  
/o/is/closure C:registered (C:registered)  
/o/is/lambda C:registered (C:registered)  
/o/is/machine C:registered (C:registered)  
/o/is/thunk C:registered (C:registered)  
/o/is/type/string generated /!/unpack/drop /!/is/type/string  
/o/last C:OSEN_PUSHFN ose_pop, ose_nip, ose_pop, ose_nip  
/o/length C:registered ose_peekType, ose_unpackDrop, ose_countItems, ose_nip  
/o/length/item generated /!/unpack/drop /!/length/item /!/nip  
/o/whence prelude.ose /!/unpack/drop /!/whence  
/o/listen higher.osen (higher.osen)  
/o/lookup generated ose_peekType, ose_unpackDrop, ose_peekType, ose_lookup, ose_peekMessageArgType, ose_swap, ose_swap, ose_swap, ose_lookup, ose_nip  
/o/lookup/inenv generated /!/unpack/drop /!/lookup/inenv  
/o/machine/new higher.osen (higher.osen)  
/o/lt C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{LT}
/o/lte C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{LTE}
/o/make/register generated /!/unpack/drop /!/make/register  
/o/map higher.osen (higher.osen)  
/o/match generated /!/unpack/drop /!/match  
/o/max C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{MAX}
/o/min C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{MIN}
/o/mod C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{MOD}
/o/mul C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{MUL}
/o/neg C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fn{NEG}
/o/neq C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{NEQ}
/o/nfill C:OSEN_PUSHFN ose_peekType, ose_unpackDrop, ose_peekType, ose_peekMessageArgType, ose_popInt32, ose_peekType, ose_getBundlePtr, ose_getLastBundleElemOffset, ose_getNthPayloadItem, ose_readByte, ose_getPayloadItemSize, ose_pnbytes, ose_readSize, ose_pnbytes, ose_incSize, ose_writeInt32, ose_writeByte, ose_writeByte, ose_nip  
/o/nil C:registered (C:registered)  
/o/not C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnunop{NOT}
/o/nth C:OSEN_PUSHFN ose_peekType, ose_unpackDrop, ose_peekType, ose_nth, ose_getLastBundleElemOffset, ose_getNthPayloadItem, ose_readByte, ose_swap, ose_swap, ose_nth, ose_nth, ose_nth, ose_peekType, ose_getBundleElemElemCount, ose_getLastBundleElemOffset, ose_unpackDrop  
/o/or C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{OR}
/o/out C:OSEN_PUSHFN ose_peekType, ose_getContextMessageOffset, ose_enter, ose_getBundleElemCount, ose_unpackDrop, ose_getBundleElemCount, ose_peekType, ose_elemToBlob, ose_swap, ose_peekType, ose_elemToBlob, ose_swap, ose_concatenateElems, ose_swap, ose_peekType, ose_peekMessageArgType, ose_peekString, ose_drop, ose_pushString, ose_concatenateElems, ose_moveStringToAddress, ose_moveElem, osevm_run, ose_pushMessage, ose_pushMessage  
/o/parse host module (host module)  
/o/pmatch generated /!/unpack/drop /!/pmatch  
/o/pop generated /!/unpack/drop /!/pop  
/o/pop/all/drop/bundle generated /!/unpack/drop /!/pop/all/drop/bundle  
/o/pow C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{POW}
/o/print prelude.ose /!/unpack/drop /!/osen/format /!/print  
/o/println prelude.ose /!/unpack/drop /!/osen/format /!/println  
/o/inspect osen_print.c the value printer with the collapse off  
/o/push generated /!/unpack/drop /!/push  
/o/put higher.osen (higher.osen)  
/o/range C:OSEN_PUSHFN ose_peekType, ose_countElems, ose_getBundleElemCount, ose_unpackDrop, ose_getBundleElemCount, ose_peekType, ose_peekMessageArgType, ose_popInt32, ose_pushMessage, ose_pushInt32, ose_push  
/o/register/flags C:registered ose_peekType, ose_unpackDrop, ose_getBundlePtr, ose_context_get_flags, ose_drop, ose_pushBundle, ose_pushMessage, ose_push  
/o/register/flags/set C:registered ose_peekType, ose_unpackDrop, ose_peekType, ose_getLastBundleElemOffset, ose_readInt32, ose_readInt32, ose_getBundleElemType, ose_readString, ose_peekMessageArgTypeAtOffset, ose_readInt32, ose_getBundleElemPayloadOffset, ose_drop, ose_getBundlePtr, ose_context_set_flags, ose_drop, ose_pushInt32  
/o/rest C:OSEN_PUSHFN ose_pop, ose_nip, ose_pushInt32, ose_decatenateElemFromStart, ose_nip  
/o/reverse C:OSEN_PUSHFN ose_peekType, ose_unpackDrop, ose_reverse  
/o/route C:OSEN_PUSHFN ose_typechk2, ose_typechk2, ose_unpackDrop, ose_peekType, ose_unpackDrop, ose_peekType, ose_swap, ose_swap, ose_swap, ose_routeWithDelegation  
/o/select C:OSEN_PUSHFN ose_typechk2, ose_typechk2, ose_unpackDrop, ose_peekType, ose_unpackDrop, ose_peekType, ose_swap, ose_swap, ose_swap, ose_selectWithDelegation  
/o/send prelude.ose /!/unpack/drop /!/send  
/o/sort C:OSEN_PUSHFN (no libose call)  
/o/sortidxs C:OSEN_PUSHFN (no libose call)  
/o/split/string/fromend generated /!/unpack/drop /!/split/string/fromend  
/o/sub C:OSEN_PUSHFN macro OSEN_WRAP_BUILTIN_BINOP \fnbinop{SUB}
/o/toblob/fromelem generated /!/unpack/drop /!/toblob/fromelem  
/o/toblob/fromitem generated /!/unpack/drop /!/toblob/fromitem  
/o/todouble generated /!/unpack/drop /!/todouble  
/o/toelem/fromblob C:registered macro OSEN_WRAP_BUILTIN  
/o/tofloat generated /!/unpack/drop /!/tofloat  
/o/toint16 generated /!/unpack/drop /!/toint16  
/o/toint32 generated /!/unpack/drop /!/toint32  
/o/toint64 generated /!/unpack/drop /!/toint64  
/o/toint8 generated /!/unpack/drop /!/toint8  
/o/tostring generated /!/unpack/drop /!/tostring  
/o/tosymbol generated /!/unpack/drop /!/tosymbol  
/o/totimetag generated /!/unpack/drop /!/totimetag  
/o/touint16 generated /!/unpack/drop /!/touint16  
/o/touint32 generated /!/unpack/drop /!/touint32  
/o/touint64 generated /!/unpack/drop /!/touint64  
/o/touint8 generated /!/unpack/drop /!/touint8  
/o/true C:registered (C:registered)  
/o/typeof0 generated /!/unpack/drop /!/typeof0  
/o/typeof1 generated /!/unpack/drop /!/typeof1  
/o/typeof2 generated /!/unpack/drop /!/typeof2  
/o/typetag/set generated /!/unpack/drop /!/typetag/set  
/o/unpack/drop generated /!/unpack/drop /!/unpack/drop  
/o/unwrap prelude.ose (prelude.ose)  
/o/zipwith C:OSEN_PUSHFN ose_unpackDrop, ose_swap, ose_swap, ose_peekType, ose_swap, ose_getBundlePtr, ose_getLastBundleElemOffset, ose_readInt32, ose_readInt32, ose_pushMessage, ose_pstrlen, ose_pstrlen, ose_pushMessage, ose_readInt32, ose_pushBundle, ose_pushMessage, ose_push, ose_swap, ose_push, ose_swap, ose_push  
/o/zipwithrest C:registered ose_blobToElem — one call; its libose spec is the meaning  

Coverage

140 names. 98 have an implementation derived from the code; 42 are left pointing at their origin, which is where a human has to look.