Ion Fusion Documentation
Release 0.38a1-SNAPSHOT (2026-04-16T19:45:37.790Z)

Module /fusion

The main Fusion language. This is the default language for Fusion scripts and the recommended language for most modules.

As the default set of recommended bindings, this module omits features that are specialized, uncommon, unsafe, or otherwise unwise. In particular, it omits non-functional features like mutation operators and mutable data types, except in vestigial cases.

Warning!

This documentation is your contract. Use of non-public and/or undocumented features, APIs, procedures, modules, etc. is NOT SUPPORTED. Behavior that is not documented here is non-contractual and is subject to change at any time. If you have any questions about supported behavior, contact us for clarification.

* procedure
(* num ...)

Returns the product of the numbers, which must be int or decimal. With no arguments, returns integer 1.

+ procedure
(+ num ...)

Returns the sum of the numbers, which must be int or decimal. With no arguments, returns integer 0.

- procedure
(- num ...+)

With two or more int or decimal numbers, returns their difference, associating to the left. With one int or decimal argument, returns its negation.

. procedure
(. value key ...)

Traverses a "path" through a data structure, folding the value through each key in turn. When the value is void, it is returned immediately and any further keys are not applied. If a key is a procedure, it must accept one argument; the procedure is applied to the current value, and the result becomes the value for the next key. Otherwise, the key and value are passed to elt to get the next value.

(. [0, 1] 0)         =>  0
(. (sexp 0 1) 1)     =>  1
(. {f:2} "f")        =>  2
(. {f:3} (quote f))  =>  3

(. [0, 1, 2, 3] size)               =>  4
(. (sexp 0 1 2 3) head)             =>  0
(. (sexp 0 1 2 3) tail)             =>  (1 2 3)
(. (sexp 0 1 2 3) tail tail head)   =>  2

Since . is a procedure, field names must be quoted or else they will be evaluated as a variable reference:

(. {f:2} f)        => ERROR: Unbound variable reference
(let [(g "f")]
  (. {f:2} g))     => 2
/ procedure
(/ dividend divisor)

Returns a decimal whose numeric value is (dividend / divisor). Both arguments must be decimals. An exception is thrown if the result cannot be represented exactly.

< procedure
(< a b)

Returns true if a is less than b. Numbers are compared without regard to precision or negative zeros; if the values have different concrete types they are both coerced to decimal. Timestamps are compared to each other without regard to precision or local offset. Annotations are ignored.

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

<= procedure
(<= a b)

Returns true if a is less than or equal to b. Numbers are compared without regard to precision or negative zeros; if the values have different concrete types they are both coerced to decimal. Timestamps are compared to each other without regard to precision or local offset. Annotations are ignored.

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

= procedure
(= left right)

Returns true if the arguments are equivalent in shape and content, possibly by coercing values to a common type. Annotations and precision are ignored.

  • Any value is = to itself.
  • Nulls of any type are = to each other.
  • Bools are = in the obvious way.
  • Numbers are = when they represent the same numeric value, without regard to precision or negative zeros. When a float is compared to an int or decimal, it is coerced to a decimal.
  • Timestamps are = when they represent the same point-in-time, without regard to precision or local offset.
  • Strings and symbols are = (interchangably) when they contain the same sequence of code points.
  • Blobs and clobs are = (interchangably) when they contain the same sequence of bytes.
  • Pairs are = when their heads and tails are =.
  • Sequences are = when they have the same size, and elements at the same index are =.
  • Structs are = when they have the same set of field names, and each name maps to a set of elements that are =.
  • Void is = only to itself.
  • Exceptions are not thrown due to mismatched types; instead the result is false.

For example:

(= null (quote a::null))             --> true
(= null null.clob)                   --> true
(= 1 1.00)                           --> true
(= 0 -0e-3)                          --> true
(= 2014T 2014-01-01T02:00+02:00)     --> true
(= 2014T 2014)                       --> false

(= "text" (quote text))              --> true
(= "text" (quote a::"text"))         --> true

(= [1, 2] (sexp 1 2.00))             --> true
(= null.list [])                     --> false

(= (struct "f" 1) (mutable_struct "f" 1.0))   --> true
(= {f:1, f:1} {f:1})                          --> false

At present, the coercion of float to decimal is precise, without rounding to approximate a prettier decimal form. This may lead to strange behavior since most decimal numbers don't have a precise binary representation:

(= 1.2 1.2e0)  --> false
(= 1.5 1.5e0)  --> true

It's possible this may change in a future release.

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

== procedure
(== left right)

Like = but does not coerce values to a common abstract supertype. Annotations and precision are ignored.

  • Any value is == to itself.
  • Nulls are only == to nulls of the same type.
  • Numbers are == when they have the same type and numeric value, without regard to precision or negative zeros.
  • Strings are only == to strings, and symbols to symbols.
  • Blobs are only == to blobs, and clobs to clobs.
  • Pairs are == when their heads and tails are ==.
  • Lists (and sexps) are == when they have the same type and size, and elements at the same index are ==.
  • Structs are == when they have the same set of field names, and each name maps to a set of elements that are ==.

For example:

(== null (quote a::null))             --> true
(== null null.clob)                   --> false
(== 1  1.)                            --> false
(== 1. 1.0)                           --> true
(=== 0. -0.)                          --> true
(== 2014T 2014-01-01T02:00+02:00)     --> true
(== 2014T 2014)                       --> false

(== "text" (quote text))              --> false
(== "text" (quote a::"text"))         --> true

(== [1, 2] (sexp 1 2   ))             --> false
(== [1, 2] (list 1 2.00))             --> false
(== [1, 2] (list 1 2   ))             --> true
(== [1, 2] (mutable_list 1 2))        --> true

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

=== procedure
(=== left right)

Like == but annotations and precision are not ignored.

  • Values are === only when their annotations are equal.
  • Decimals are === only when they have the same numeric value and precision. Negative zeros are not === to positive zeros.
  • Timestamps are === only when they represent the same point-in-time and have the same precision and local offset.

For example:

(=== null (quote a::null))             --> false
(=== (quote a::null) (quote a::null))  --> true
(=== null null.clob)                   --> false
(=== 1   1.)                           --> false
(=== 1.  1.0)                          --> false
(=== 1.0 1.0)                          --> true
(=== 0. -0.)                           --> false

(=== 2014T 2014-01-01T02:00+02:00)     --> false
(=== 2014-01-01T00:00+00:00
     2014-01-01T00:00-00:00)           --> false

(=== (quote    a::1) (quote a::a::1))  --> false
(=== (quote b::a::1) (quote a::b::1))  --> false

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

> procedure
(> a b)

Returns true if a is greater than b. Numbers are compared without regard to precision or negative zeros; if the values have different concrete types they are both coerced to decimal. Timestamps are compared to each other without regard to precision or local offset. Annotations are ignored.

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

>= procedure
(>= a b)

Returns true if a is greater than or equal to b. Numbers are compared without regard to precision or negative zeros; if the values have different concrete types they are both coerced to decimal. Timestamps are compared to each other without regard to precision or local offset. Annotations are ignored.

Warning: The behavior of this procedure is undefined for values +inf, -inf, and nan. See issue #64.

add procedure
(add sequence element)

Returns a sequence with all the elements of sequence and the element. The result sequence is similar to the input, its size is one greater, and it may share structure with other sequences.

In general, the position of element within the result is not specified, but particular sequence types may do so.

  • For lists, the element becomes the last element of the result.
  • For sexps, the element becomes the head of the result.
adjust_day procedure
(adjust_day ts period)

Returns a timestamp that's period days after (or before, if negative) ts. The result will have the same precision and local offset.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

adjust_hour procedure
(adjust_hour ts period)

Returns a timestamp that's period hours after (or before, if negative) ts. The result will have the same precision and local offset.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

adjust_minute procedure
(adjust_minute ts period)

Returns a timestamp that's period minutes after (or before, if negative) ts. The result will have the same precision and local offset.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

adjust_month procedure
(adjust_month ts period)

Returns a timestamp that's period months after (or before, if negative) ts. The result will have the same precision and local offset. In general, only the year and month fields will change, but the day may change to account for leap-days.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

adjust_second procedure
(adjust_second ts period)

Returns a timestamp that's period seconds after (or before, if negative) ts. The result will have the same precision and local offset.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

adjust_year procedure
(adjust_year ts period)

Returns a timestamp that's period years after (or before, if negative) ts. The result will have the same precision and local offset. In general, only the year field will change, but the day may change to account for leap-days.

ts must be a non-null timestamp and period must be a non-null int (limited to the 32-bit range).

all_defined_out syntax
(all_defined_out)

A provide clause that exports all bindings defined by the enclosing module. Imported bindings are not exported.

This form can only appear within provide.

always procedure
(always v)

Returns a procedure that accepts (and ignores) any number of arguments and always returns v.

and syntax
(and expr ...)

Evaluates the exprs from left to right, returning the first untruthy value that results (and ignoring further expressions). If they all return truthy values, the last one is returned.

The last expr is in tail position. Given no exprs, the result is true.

annotate procedure
(annotate value text ...)

Applies the given annotations to a value, returning a (shallow) copy if necessary to avoid mutating it. Any annotations on value are removed, so (annotate value) effectively de-annotates a value.

The value must be annotatable; that is, it must be one of the Ion types. The text arguments must be non-null strings or symbols.

(annotate 123 "a")              =>  a::123
(let [(v (quote a::123))]
  (annotate v))                 =>  123
(let [(anns ["a", (quote b)])]
  (apply annotate 123 anns))    =>  a::b::123

To extract annotations from a value, use annotations.

annotations procedure
(annotations value)

Returns a non-null immutable list of symbols containing the user type annotations on the value.

(annotations 123)                =>  []
(annotations (quote a::b::123))  =>  [a, b]

To put annotations onto a value, use annotate.

any procedure
(any pred collection)

Applies the one-argument predicate pred to the elements of collection; the first time pred returns a truthy value that truthy value is returned and no more elements are visited. If no call returns a truthy value, then the result is that of the final predicate call, or false if the collection is empty.

When collection is a sequence, the elements are visited in order, and the application of pred to the final element of the sequence is in tail position.

append procedure
(append sequence ...+)

Returns a sequence with the concatenation of all the elements of the sequences. The result has same type and annotations as the first sequence. Any argument that is null.list (or null.sexp) is treated as if it were an empty list (or empty sexp).

apply procedure
(apply proc arg ... sequence)

Calls the given proc with arguments that are the (optional) args prepended to the elements of sequence. The proc is called in tail position.

(apply + [1, 2])             =>  3
(apply + 10 11 (sexp 1 2))   =>  24
assert syntax
(assert expr message ...)

Evaluates the expr, throwing an exception if the result isn't truthy. The exception displays the messages, which are only evaluated on failure.

begin syntax
(begin expr ...)

Evaluates the exprs in order, returning the final result. The last expr is in tail position. If there are no exprs the result is void.

call_with_handler procedure
(call_with_handler handler thunk)

Installs the handler then calls the thunk. If raise is called while the thunk is evaluated, the handler is called with the raised value. This happens in tail position with respect to call_with_handler.

The handler must be a procedure that accepts one argument: the raised value.

Most code should use the with_handlers syntax form instead of this procedure, which is prone to error by using a non-thunk body expression.

ceiling procedure
(ceiling number)

Returns the smallest int greater than or equal to number (that is, truncate toward positive infinity). The input must be a non-null int or decimal, and the result is an int.

choose procedure
(choose pred sequence)

Applies the one-argument predicate pred to each element of sequence, returning a new sequence of the same type, containing the elements (in order) for which pred returns truthy.

compose procedure
(compose p1 p2)

Returns a procedure that first applies p2 to its (single) argument, and then applies p1 to the (single) result.

cond syntax
(cond (test body ...) ...)

Evaluates the test expressions left to right until one returns a truthy value, then evaluates the corresponding body expressions in tail position. If no test is truthy, the result is void.

conjoin procedure
(conjoin p1 p2)

Returns a single-argument predicate that is the conjunction of the single-argument predicates p1 and p2 as with and, applying them left to right until one returns an untruthy value.

In other words, the result is similar to using and to compose calls to the predicates.

curry_left procedure
(curry_left proc arg ...+)

Returns a procedure based on proc and the given leftmost args.

(define prepend56
  (curry_left append_m [5, 6]))
(prepend56)                           --> [5,6]
(prepend56 [1])                       --> [5,6,1]

(define prepend567
  (curry_left append_m [5, 6] [7]))
(prepend567 [1] [2,3])                --> [5,6,7,1,2,3]
curry_right procedure
(curry_right proc arg ...+)

Returns a procedure based on proc and the given rightmost args.

(define append56
  (curry_right append_m [5, 6]))
(append56)                             --> [5,6]
(append56 [1])                         --> [1,5,6]

(define append567
  (curry_right append_m [5, 6] [7]))
(append567 [1] [2,3])                  --> [1,2,3,5,6,7]
decimal procedure
(decimal coefficient)
(decimal coefficient exponent)

Returns the decimal value from the coefficient and optional exponent. The coefficient must be a number. The exponent, if supplied, must be a non-null int. Returns null.decimal when coefficient is null.

Examples:

(decimal null.float) // null.decimal
(decimal 1234e-2)    // 12.34
(decimal 1.21e1 0)   // 12.1
(decimal 4.2 1)      // 42.
(decimal 1234 -2)    // 12.34
define syntax
(define id value)

Binds a namespace-level variable id to the result of value.

At top-level, the value expression is evaluated before top-level bindings for the ids are created.

(define (id arg ...) body ...+)

Defines a procedure id, with formal arguments arg ... and the body. This form is equivalent to (define id (lambda (arg ...) body ...)).

define_values syntax
(define_values (id ...) expr)

Binds a number of namespace-level variables to the multiple results of an expression. If the expr returns a different number of values than there are ids, a contract exception is raised.

At top-level, the expr is evaluated before top-level bindings for the ids are created.

disjoin procedure
(disjoin p1 p2)

Returns a single-argument predicate that is the disjunction of the single-argument predicates p1 and p2 as with or, applying them left to right until one returns a truthy value.

In other words, the result is similar to using or to compose calls to the predicates.

display procedure
(display value ...)

Outputs a text representation of the values to the current output port, in a form meant for human consumption. When a value is an unannotated string or symbol, its character data is written as-is, unquoted and unescaped. All other values are rendered as by write. No characters are written between the values. In general, the result will be unreadable by the Fusion and Ion readers.

display_to_string procedure
(display_to_string value ...)

Returns a string with a human-oriented text representation of the values. The output format is as defined by display.

displayln procedure
(displayln value ...)

Displays the values, then a newline.

do procedure
(do proc collection)

Applies the one-argument procedure proc to the elements of collection, ignoring any results. Returns void.

When collection is a sequence, the elements are visited in order.

See also: struct_do

element procedure
(element collection key)

Returns an element within a collection. The collection must be a non-null, non-empty list, sexp, or struct. The key must have a type appropriate for the collection: an int for lists or sexps, a string or symbol for structs.

(element [0, 1] 0)         =>  0
(element (sexp 0 1) 1)     =>  1
(element {f:2} "f")        =>  2
(element {f:3} (quote f))  =>  3

Since element is a procedure, field names must be quoted or else they will be evaluated as a variable reference:

(element {f:2} f)        => ERROR: Unbound variable reference
(let [(g "f")]
  (element {f:2} g))     => 2

An exception is raised if the collection has an unsupported type, if the key isn't appropriate for the collection, or if the key doesn't identify an element within the collection.

(element [0, 1] 2)       =>  ERROR
(element [0, 1] "2")     =>  ERROR
(element {f:2} "g")      =>  ERROR
elt procedure
(elt collection key)

Returns an element within a collection, being lenient. The collection must be a list, sexp, struct, or void. The key must have a type appropriate for the collection: an int for lists or sexps, a string or symbol for structs.

(elt [0, 1] 0)         =>  0
(elt (sexp 0 1) 1)     =>  1
(elt {f:2} "f")        =>  2
(elt {f:3} (quote f))  =>  3

If the collection is empty, null, or void, the result is void. If the key isn't appropriate for the collection, or if the key doesn't identify an element within the collection, the result is void.

(elt null.list 0)    =>  void
(elt [0, 1] 2)       =>  void
(elt [0, 1] "2")     =>  void
(elt {f:2} "g")      =>  void

Since elt is a procedure, field names must be quoted or else they will be evaluated as a variable reference:

(elt {f:2} f)        => ERROR: Unbound variable reference
(let [(g "f")]
  (elt {f:2} g))     => 2

An exception is raised if the collection has an unsupported type.

empty_iterator constant

An iterator with no elements. (iterator_has_next empty_iterator) always returns false, and (iterator_next empty_iterator) always throws an exception.

empty_series constant

A series that produces no elements.

eof constant

A unique value that denotes an end-of-file condition.

epoch_millis_to_timestamp procedure
(epoch_millis_to_timestamp epoch_millis)

Returns a timestamp for the point in time given as the number of milliseconds since 1970-01-01T00:00Z. The epoch_millis may be a decimal or int.

every procedure
(every pred collection)

Applies the one-argument predicate pred to the elements of collection; the first time pred returns an untruthy value that untruthy value is returned and no more elements are visited. If no call returns an untruthy value, then the result is that of the final predicate call, or true if the collection is empty. When collection is a sequence, the elements are visited in order, and the application of pred to the final element of the sequence is in tail position.

find procedure
(find pred collection)

Applies the one-argument predicate pred to each element of collection; the first time pred returns a truthy value that element is returned. If no such element is found, the result is void.

When collection is a sequence, the elements are visited in order.

When collection is a struct, the "elements" of the collection are its values (as opposed to its key-value pairs): the predicate will be applied on each value, and the result is either one of those values or void.

first procedure
(first sequence)

Returns the first element in the sequence. Fails if the sequence has no elements.

floor procedure
(floor number)

Returns the largest int less than or equal to number (that is, truncate toward negative infinity). The input must be a non-null int or decimal, and the result is an int.

fold_left procedure
(fold_left proc init sequence ...)

Applies the given procedure to zero or more sequences producing a single value determined by proc. proc must take n+1 arguments where n is the number of sequences. The proc's first argument is the combined return value and is initially set to init. Sequences are visited left to right with the result of fold_left being the value produced by the last application of proc after one or more sequences runs out of values. If no sequences are given or any sequence is empty, the result is init.

Adding numbers:

(fold_left + 0 (sexp 1 2 3) [4, 5, 6, 7])  => 21

That performs these procedure calls:

  (+ 0 1 4)  => 5
  (+ 5 2 5)  => 12
  (+ 12 3 6) => 21

Reversing a linked list:

(fold_left
  (lambda (t h) (pair h t))
  (quote ())
  (sexp 1 2 3 4 5)) => (sexp 5 4 3 2 1)

Vizualizing fold_left:

(fold_left f z (1 2 3 4 5))

   . --------------------> f
  / \                     / \
 1   .                   f   5
    / \                 / \
   2   .               f   4
      / \             / \
     3   .           f   3
        / \         / \
       4   .       f   2
          / \     / \
         5   ()  z   1


(fold_left f z (1 2 3 4 5) (6 7 8 9 0))

   . --------------------> f
  /|\                     /|\
 1 6 .                   f 5 0
    /|\                 /|\
   2 7 .               f 4 9
      /|\             /|\
     3 8 .           f 3 8
        /|\         /|\
       4 9 .       f 2 7
          /|\     /|\
         5 0 ()  z 1 6
for syntax
(for [for-clause, ...] body ...+)

for-clause := (id series_expr)
            | ((id ...+) series_expr)

Iterates series in parallel, binding the corresponding ids to the values produced at each step and then evaluating body.

The series_exprs are first evaluated left-to-right, and each must return a series value. While every series can produce more elements, they are retrieved in left-to-right order, bound to their ids at new storage slots, and then the body is evaluated. The results of the body are ignored; the result of for is always void.

If no for-clauses are provided, then the body is executed once.

(for [(a [1, 2]),
      (b [5, 7])]
  (display (sexp a b)))
=>
(1 5)(2 7)
for_fold syntax
(for_fold
  [(accum-id init-expr), ...]
  [for-clause, ...]
  body ...+)

Iterates using explicit accumulators. The first clause is used to initialize any accumulator bindings before iteration begins; new accumulator locations are used for each cycle. The final body expression must produce the same number of values as there are accum-ids, and those become the accumulator values for the next cycle.

The results of the for_fold expression are the final accumulator values.

(for_fold
  [(result "")]
  [((name value) { "a": 1, "b": 2 })]
  (string_append result
    (if (== result "") "" " and ")
    (display_to_string name "=" value)))    => "a=1 and b=2"
for_list syntax
(for_list [for-clause, ...] body ...+)

Like for, but returning a stretchy list of the body results.

(for_list
  [(even [0, 2, 4]),
   (odd  [1, 3, 5])]
  (+ even odd))             =>  [1, 5, 9]
for_sexp syntax
(for_sexp [for-clause, ...] body ...+)

Like for, but returning a sexp of the body results.

(for_sexp
  [(even [0, 2, 4]),
   (odd  [1, 3, 5])]
  (+ even odd))             =>  (1 5 9)
for_struct syntax
(for_struct [for-clause, ...] body ...+)

Like for, but returning a struct. The body must return two values, a field name (string or symbol) and its corresponding element.

(for_struct
  [(key (quote (a b c))),
   (val [1, 2, 3])]
  (values key val))             =>  {a:1, b:2, c:3}

If the same field name is returned by multiple evaluations of the body, the resulting struct will have corresponding repeated fields:

(for_struct
  [(key ["a", "b", "a"]),
   (val [1, 2, 3])]
  (values key val))             =>  {a:1, a:3, b:2}
fors syntax
(fors [for-clause, ...] body ...+)

Like for, but the series are iterated in nested loops. The scope of each binding identifier includes the series_exprs of later for-clauses, as well as the body.

(fors [(a [1, 2]),
       (b [5, 7])]
  (display (sexp a b)))
=>
(1 5)(1 7)(2 5)(2 7)
fors_fold syntax
(fors_fold
  [(accum-id init-expr), ...]
  [for-clause, ...]
  body ...+)

Like for_fold, except the series are iterated in nested loops instead of in parallel. Each clause's bindings are made available to the following clauses as well as the body.

fors_list syntax
(fors_list [for-clause, ...] body ...+)

Like fors, but returning a stretchy list of the body results.

(fors_list [(a [1,2]),
            (b [5,7])]
  (* a b))                             => [5, 7, 10, 14]

(define data [{a:[ {b:1}, {b:2} ]},
              {a:[ {b:3}, {b:4} ]} ])
(fors_list [(x data),
            (y (. x "a"))]
  (. y "b"))                           => [1, 2, 3, 4]

(define data [[[1],[2]],[[3],[4]]])
(fors_list [(x data),
            (y x),
            (z y)]
  z)                                   => [1, 2, 3, 4]
fors_sexp syntax
(fors_sexp [for-clause, ...] body ...+)

Like fors, but returning a sexp of the body results.

(fors_sexp [(a [1, 2]),
            (b [5, 7])]
  (* a b))                             => (5 7 10 14)
fors_struct syntax
(fors_struct [for-clause, ...] body ...+)

Like fors, but returning a struct. The body must return two values, a field name (string or symbol) and its corresponding element. As with for_struct, the result can have repeated fields:

(fors_struct [(v [1, 2]),
              (k ["a", "b"])]
  (values k v))                 => {a:1, a:2, b:1, b:2}
has_key procedure
(has_key collection key)

Determines whether a collection has a mapping for a given key. When has_key returns true, then (element collection key) will succeed.

Note that the keys of a sequence are the zero-based integer indices of the elements within the sequence, not the elements themselves.

(has_key {f:12} "f")           ==> true
(has_key [3,true,2014T] 0)     ==> true
(has_key [3,true,2014T] 3)     ==> false
(has_key [3,true,2014T] null)  ==> false
ident procedure
(ident left right)

Returns true if and only if the arguments are the same object; that is, when they have the same object identity.

(ident 1 (quote a::1))                   --> false
(let [(v "hi")] (ident v v))             --> true
(let [(v (quote a::"hi"))] (ident v v))  --> true
(ident (void) (void))                    --> true

At the implementation level, ident is a trivial pointer comparison. As such, it exposes some implementation details that may change over time or across platforms.

Since Fusion symbols are interned, those with the same text and annotations are always ident:

(ident (string_to_symbol "barn")
       (quote barn))                     --> true
(ident (string_to_symbol "barn")
       (string_to_symbol
         (string_append "ba" "rn")))     --> true
(ident (quote a::barn) (quote barn))     --> false

Fusion allows implementation optimizations that copy and/or intern numeric values as needed. Therefore there's no promise of stable object identity for numbers, and this operator may behave in unexpected and implementation-defined ways when applied to them.

(ident 2 (+ 1 1))                        --> // unspecified
(let [(v 2)] (ident v v))                --> // unspecified

Other than symbols, it is not specified whether literals or quoted data are interned, so there's no promise of identity across two different syntactic instances of the same value:

(ident 10600439 10600439)                --> // unspecified
(ident "hi" "hi")                        --> // unspecified
(ident (quote a::"hi") (quote a::"hi"))  --> // unspecified
identity procedure
(identity v)

Returns v.

if syntax
(if test then else)

Evaluates the test expression first. If the result is truthy, evaluates the then expression and returns its value. Otherwise, evaluates the else expression and returns its value.

All values are "truthy" except for false, void, and any variant of null.

Note that only one of then or else expressions is evaluated, and both are in tail position.

For cases that need only one outcome, use when or unless.

in_port procedure
(in_port)

Returns a series of elements produced by calling read. In other words, the series produces the data on the current Ion input port.

The current port can be locally parameterized to affect iteration over Ion data in files, lobs, or strings:

(with_ion_from_file "document.ion"
  // The with_ion_from functions take a thunk:
  (lambda ()
    (series_to_list (in_port))))
=>
[1, k, {a:false}]

See /fusion/io for other ways to parameterize the current Ion input port.

in_producer procedure
(in_producer producer stop_pred)

Returns a series containing the results from calls to the producer procedure.

At each step, the producer is invoked with no argument. The stop_pred is then applied to the result(s), and if it returns truthy then the series ends (without including those values). Otherwise the producer's results are produced by the series.

int_to_string procedure
(int_to_string int)

Converts an int to a string. Returns null.string when given null.int.

ionize procedure
(ionize value)

Outputs an Ion text representation of value to the current output port, throwing an exception if the value contains any non-Ionizable data like closures.

See write for an alternative that doesn't fail an non-Ionizable inputs.

ionize_to_blob procedure
(ionize_to_blob value)

Encodes an Ion binary representation of value, throwing an exception if the value contains any non-Ionizable data like closures. The result is a blob containing an Ion binary document.

ionize_to_string procedure
(ionize_to_string value)

Encodes an Ion text representation of value, throwing an exception if the value contains any non-Ionizable data like closures. The result is a string containing an Ion text document.

is_argument_error procedure
(is_argument_error v)

Determines whether a value is an exception of type argument_error. Returns true or false.

is_arity_error procedure
(is_arity_error v)

Determines whether a value is an exception of type arity_error. Returns true or false.

is_blob procedure
(is_blob value)

Determines whether a value is of type blob, returning true or false.

is_bool procedure
(is_bool value)

Determines whether a value is of type bool, returning true or false.

is_clob procedure
(is_clob value)

Determines whether a value is of type clob, returning true or false.

is_collection procedure
(is_collection value)

Determines whether value is a collection (struct, list, or sexp), returning true or false.

is_contract_error procedure
(is_contract_error v)

Determines whether a value is an exception of type contract_error. Returns true or false.

is_decimal procedure
(is_decimal value)

Determines whether a value is of type decimal, returning true or false.

is_empty procedure
(is_empty collection)

Returns true if the size of the collection is zero, otherwise returns false.

is_eof procedure
(is_eof value)

Determines whether a value is the Fusion end-of-file value. This value is bound to the name eof.

is_error_exn procedure
(is_error_exn v)

Determines whether a value is an exception of type error_exn. Returns true or false.

is_exn procedure
(is_exn v)

Determines whether a value is an exception of type exn. Returns true or false.

is_false procedure
(is_false v)

Returns true when the argument is false (annotated or not), or false otherwise.

Equivalent to:

(== v false)
is_float procedure
(is_float value)

Determines whether a value is of type float, returning true or false.

is_int procedure
(is_int value)

Determines whether a value is of type int, returning true or false.

is_iterator procedure
(is_iterator value)

Checks if the value is an iterator. Returns true or false.

is_list procedure
(is_list value)

Determines whether value is a list, returning true or false.

is_null procedure
 (is_null value)

Returns true when value is any Ion null, false otherwise.

is_null_null procedure
(is_null_null value)

Determines whether a value is null.null, returning true or false.

is_pair procedure
(is_pair value)

Determines whether value is a pair, returning true or false.

is_procedure procedure
(is_procedure value)

Returns true when value is a procedure, false otherwise.

is_result_error procedure
(is_result_error v)

Determines whether a value is an exception of type result_error. Returns true or false.

is_sequence procedure
(is_sequence value)

Determines whether value is a sequence, returning true or false.

is_series procedure
(is_series value)

Determines whether a value is a series that can be consumed by a for comprehension.

is_sexp procedure
(is_sexp value)

Determines whether a value is a sexp, returning true or false.

is_string procedure
(is_string value)

Determines whether a value is of type string, returning true or false.

is_struct procedure
(is_struct value)

Determines whether value is a struct, returning true or false.

is_symbol procedure
(is_symbol value)

Determines whether a value is of type symbol, returning true or false.

is_syntax_error procedure
(is_syntax_error v)

Determines whether a value is an exception of type syntax_error. Returns true or false.

is_timestamp procedure
(is_timestamp value)

Determines whether a value is of type timestamp, returning true or false.

is_true procedure
(is_true v)

Returns true when the argument is true (annotated or not), or false otherwise.

Equivalent to:

(== v true)
is_truthy procedure
(is_truthy v)

Returns true when the argument is truthy, or false otherwise. Fusion defines truthiness as follows:

  • Every value is truthy except for false, void, and any variant of null.

Equivalent to:

(if v true false)

See also: Truthiness

is_unbound_error procedure
(is_unbound_error v)

Determines whether a value is an exception of type unbound_error. Returns true or false.

is_untruthy procedure
(is_untruthy v)

Returns true when the argument is not truthy, or false otherwise. The untruthy values are false, void, and any variant of null.

Equivalent to:

(if v false true)

See also: Truthiness

is_void procedure
(is_void value)

Determines whether a value is the Fusion void value.

iterator_append procedure
(iterator_append iter1 iter2)

Returns an iterator that provides all the elements of iter1 and then all the elements of iter2.

iterator_choose procedure
(iterator_choose pred iter)

Returns an iterator whose elements are those provided by iter that satisfy predicate pred.

iterator_find procedure
(iterator_find pred iter)

Returns the first element of iter that satisfies predicate pred. If no element satisfies the predicate, the result is void.

iterator_has_next procedure
(iterator_has_next iterator)

Checks if the iterator will provide another value when iterator_next is called. Returns true or false.

After this procedure returns false for some iterator instance, all subsequent calls of iterator_has_next on the same instance are expected to return false, and all subsequent calls of iterator_next are expected to throw an exception.

iterator_map procedure
(iterator_map proc iter)

Returns an iterator whose elements are the results of applying proc to the corresponding elements of iter.

iterator_map_splicing procedure
(iterator_map_splicing proc iter)

Returns an iterator that applies an iterator-making proc to each element of iter, splicing the inner iterators into a single outer iterator.

iterator_next procedure
(iterator_next iterator)

Returns the next element of the iterator. When the iterator has no more elements, an exception is thrown.

jsonize_to_string procedure
(jsonize_to_string value)

Encodes an JSON text representation of value, throwing an exception if the value contains any non-Ionizable data like closures. The result is a string containing a JSON text document.

Compared to ionize_to_string, this method applies these conversions:

  • All annotations are suppressed.
  • Nulls of any type are printed as JSON null.
  • Blobs are printed as strings, containing Base64.
  • Clobs are printed as strings, containing only Unicode code points U+00 through U+FF.
  • Sexps are printed as lists.
  • Symbols are printed as strings.
  • Timestamps are printed as strings, using Ion timestamp format.
lambda syntax
(lambda (arg ...) body ...+)

Returns a procedure. When invoked, the caller's arguments are bound to the arg identifiers (the formal arguments) and the body is evaluated and returned. body may be one or more forms; the last form is in tail position and its result is the result of the procedure invocation.

The Fusion runtime system may optimize procedure instantiation, so it is unspecified whether one or more lambda expressions will return distinct or identical objects for any evaluation.

(lambda rest_id body ...+)

This variant, which declares a single formal argument rather than a sequence of them, returns a procedure that accepts any number of values, which are collected into an immutable sexp and bound to the rest_id:

((lambda args args) 8 9 10)   --> (8 9 10)
last procedure
(last sequence)

Returns the last element in the sequence. Fails if the sequence has no elements.

let syntax
(let ((ident expr) ...) body ...+)

Evaluates the exprs left to right, then binds each ident to its corresponding result, then evaluates body. The scope of the idents only covers the body, not the exprs.

body may be one or more forms; the last form is in tail position and its result is the result of the entire expression.

(let loop_id [(ident expr), ...] body ...+)

This variant also creates a procedure, bound to the given name loop_id, that accepts the same number of arguments as there are idents. When invoked, the procedure binds the idents to the arguments and evaluates the body.

For example, this snippet loops through the standard input port and writes the title field of each item:

(let loop [(item (read))]
  (unless (is_eof item)
    (let [(title (. item "title"))]
      (writeln title)
      (loop (read)))))

(While illustrative of looping, this is not the recommended way to accomplish this; see /fusion/io for better approaches.)

let_values syntax
(let_values (((ident ...) expr) ...) body ...+)

Captures multiple results, creating local bindings for the idents, with the body in scope. The exprs are evaluated left-to-right, and must return as many values as there are corresponding idents, which are then bound to those results. After the bindings are installed the body is evaluated. body may be one or more forms; the last form is in tail position and its result is the result of the entire expression.

letrec syntax
(letrec ((ident expr) ...) body ...+)

Creates new binding locations for each ident, binds them to their exprs, then evaluates body. The exprs are evaluated left-to-right, and the idents are bound in all exprs and bodys. body may be one or more forms; the result of the last form is the result of the entire expression.

lets syntax
(lets [(ident expr), ...] body ...+)

Like let, but each binding is created (and its expr evaluated) one by one, and the idents are bound in the following exprs as well as the body.

(lets [(a 1),
       (b (+ a 1))]
  [a, b])            => [1, 2]
list procedure
(list value ...)

Makes a fresh, immutable list containing the given values.

list_element procedure
(list_element list pos)

Returns the element of list at (zero-based) position pos. An exception is thrown if the position is out of bounds.

list_from_iterator procedure
(list_from_iterator iterator)

Creates a stretchy list with the elements of iterator, in the same order.

At present, this procedure will fail if the iterator returns multiple results.

list_iterator procedure
(list_iterator list)

Returns an iterator over the elements of list.

lob_digest procedure
(lob_digest lob algorithm)

Generates a message digest for the content of a lob, using the given algorithm. The lob must be a non-null blob or clob containing the bytes to be digested. The algorithm must be a string such as "SHA-256". The result is a non-null blob.

Supported algorithms are "SHA-256" and "SHA-512".

lob_to_hex procedure
(lob_to_hex lob)

Converts a lob to its hex encoding as a string. Returns null.string when given null.clob or null.blob. The returned hex string does not contain a '0x' prefix, and will only contain the characters [0-9a-f].

make_iterator procedure
(make_iterator has_next_proc next_proc)

Returns an iterator that delegates iterator_has_next and iterator_next to the given procedures, which are usually closures with shared state.

make_parameter procedure
(make_parameter value)

Makes a new dynamic parameter procedure. The initial value of the parameter is value.

map procedure
(map proc sequence)

Applies the one-argument procedure proc to each element of sequence, returning a new sequence of the same type, containing the results in order.

module syntax
(module name language body ...+)

Declares a module containing the given body. The name must be a symbol; it is ignored when loading a module from a file.

The language must be an absolute module path. The denoted module is instantiated and all of its provided bindings are immediately imported. This "bootstraps" the module with a set of bindings that form the base semantics for the body. Unlike bindings that are required, these bindings can be shadowed by module-level definitions and by require statements.

When compiling a module, the body forms are partially macro-expanded in order to discover certain core forms like require and provide. The former are handled immediately, before other forms. The latter are handled after all other forms. At module level, the elements within begin forms are spliced into the enclosing module body, replacing the single begin form with its elements. This effectively enables module-level macro uses to expand into multiple forms.

negate procedure
(negate p)

Returns a single-argument procedure that applies not to the result of the single-argument procedure p.

none procedure
(none pred collection)

Applies the one-argument predicate 'pred' to the elements of collection. Returns false if the predicate returns a truthy value for any element, true if none do, and true if the collection is empty.

not procedure
(not value)

Returns true if value is untruthy, false if value is truthy. Truthiness is as defined by if.

object_name procedure
(object_name v)

Returns the name of v if it has one, otherwise void.

At present, only procedures bound by define have names, which are symbols. In general, not all object names are symbols.

only_in syntax
(only_in module_path id ...)

A require clause that imports only the given ids from a module. If an id is not provided by the module, a syntax error is reported.

Bindings introduced by this form use the lexical context of the module path, not that of the given identifiers.

This form can only appear within require.

or syntax
(or expr ...)

Evaluates the exprs from left to right, returning the first truthy value that results (and ignoring further expressions). If they all return untruthy values, the last one is returned.

The last expr is in tail position. Given no exprs, the result is false.

pair procedure
(pair head tail)

Makes a fresh, immutable pair containing the given head and tail.

parameterize syntax
(parameterize [(param expr), ...] body ...+)

Dynamically binds the params to the expr values while evaluating the body. The params are evaluated first, in order; each must result in a dynamic parameter. The exprs are then evaluated in order, and then the parameters are changed to their results for the dynamic extent of the body.

The body may be one or more forms; the result of the last form is the result of the entire expression.

prefix_in syntax
(prefix_in prefix_id module_path)

A require clause that adjusts each identifier to be bound by prefixing it with prefix_id.

Bindings introduced by this form use the lexical context of the module path, not that of the prefix identifier.

This form can only appear within require.

provide syntax
(provide provide_clause ...)

Declares bindings to be exported from the enclosing module. This form may only appear at module level.

Each provide_clause denotes some names to be exported. The following clause forms are allowed:

  • An identifier defined at module-level or imported from another module.
  • all_defined_out exports all module-level definitions.
  • rename_out exports selected bindings, giving them new names on the way out.

Within a module, a single provide form with multiple clauses behaves identically to multiple provide forms with single clauses.

put procedure
(put struct key value)

Functionally modifies a field of a struct, returning a new struct of the same type. Any existing fields (including repeats) named by the key are replaced by a single field with the value.

(define s {a:1, b:2, b:3})

(put s "a" 4)    ==> {b:2,b:3,a:4}
(put s "b" 5)    ==> {b:5,a:1}
(put s "c" 6)    ==> {b:2,b:3,c:6,a:1}
s                ==> {b:2,b:3,a:1}
quasiquote syntax
(quasiquote template)

Like quote, but the template datum may contain nested unquote forms that act as escapes. The unquoted expression is evaluated when the containing quasiquote is evaluated, and its result is inserted into the containing quoted datum.

(quasiquote [(+ 1 2), (unquote (+ 1 2))])

==> [(+ 1 2), 3]

unquote forms only escape one "level" of quasiquotation:

(let [(v 1)]
  (quasiquote (a (quasiquote (b (unquote v) (unquote (unquote v)))))))

==> (a (quasiquote (b (unquote v) (unquote 1))))
quote syntax
(quote datum)

Returns the Ion datum as-is, without evaluation.

raise procedure
(raise value)

Passes the value to the thread's current exception handler. Any type of value can the raised, but most application code should use the raise_*_error procedures to raise subtypes of exn.

raise_argument_error procedure
(raise_argument_error name expected bad_pos value ...+)

Raises an argument_error denoting contract failure due to a procedure being called with unacceptable argument values. The name text (string or symbol) identifies the procedure. The expected string describes the relevant contract. bad_pos is the zero-based position of the bad argument; a negative value means that a specific argument is not implicated. The values are the arguments passed to the procedure.

Note that an argument_error IS-A contract_error.

raise_arity_error procedure
(raise_arity_error name arity actual_arg ...)

Raises an arity_error denoting contract failure due to a procedure receiving an unacceptable number of arguments. The name text (string or symbol) identifies the called procedure. The arity is an int indicating the expected arity. The actual_args are the values passed to the procedure.

Note that an arity_error IS-A contract_error.

raise_contract_error procedure
(raise_contract_error name message)

Raises a contract_error denoting a general contract failure. The name text (string or symbol) identifies the procedure. The message string describes the relevant contract failure.

raise_result_error procedure
(raise_result_error name expected value)

Raises a result_error denoting contract failure due to a procedure returning an unacceptable value. The name text (string or symbol) identifies the calling procedure. The expected string describes the relevant contract. The value is the faulty result.

Note that a result_error IS-A contract_error.

random procedure
(random)
(random max)

Returns a random float value between 0.0 (inclusive) and 1.0 (exclusive) when no additional arguments are provided. When max is provided, it must be a positive integer, and the result is a random number between 0 (inclusive) and max (exclusive).

Examples:

(random)    // Returns a decimal value: 0.0 <= value < 1.0
(random 45) // Returns an int value:    0   <= value < 45
read procedure
(read)

Reads an Ion value from the current Ion input port. Returns eof when there's no more data.

Here's one way to print to stdout the address fields of the structs on stdin:

(let loop [(value (read))]
  (unless (is_eof value)
    (writeln (. value "address"))
    (loop (read))))

In general, read is more low-level than necessary; see /fusion/io for more options.

remove_keys procedure
(remove_keys struct name ...)

Returns a struct derived from struct without fields with the given names. If the input is null.struct then the result is null.struct. The result will have the same annotations as struct.

rename_in syntax
(rename_in module_path (exported_id local_id) ...)

A require clause that imports each exported_id using the name local_id. If an exported_id is not provided by the module, a syntax error is reported.

In contrast to other require-clauses, bindings introduced by this form use the lexical context of the local_ids, not that of the module path.

This form can only appear within require.

Warning: This behaves differently than Racket's rename-in, which imports everything from the given module (or nested require-clause) while renaming selected items from that set. In contrast, this form ignores exported bindings that are not renamed.

rename_out syntax
(rename_out (local_id exported_id) ...)

A provide clause that exports each local_id using the name exported_id. This effectively renames the binding on export.

This form can only appear within provide.

require syntax
(require require_clause ...+)

Declares bindings to be imported into the enclosing namespace. This form may only appear at module level or top level.

Each require_clause denotes some bindings to be imported. The following clause forms are allowed:

  • A string or symbol containing a module path; all names provided by the referenced module are imported. The bindings introduced by this form use the lexical context of the module path.
  • only_in enumerates a set of names to import.
  • prefix_in provides a prefix to imported bindings.
  • rename_in renames specified bindings.

Within a module, require declarations are processed before other forms, regardless of their order within the module source, and imported bindings are scoped across the entire module. No identifier may be imported multiple times, unless all such bindings refer to the same originating definition. Furthermore, no identifier may have both an import and a module-level definition. In other words: module-level bindings introduced by require or define must not conflict, although either may shadow same-named bindings introduced by the module's language declaration.

At top level, require will replace an existing import, and may shadow an existing top-level definition.

retain_keys procedure
(retain_keys struct name ...)

Returns a struct derived from struct with only fields with the given names. If the input is null.struct then the result is null.struct. The result will have the same annotations as struct.

reverse procedure
(reverse sexp)

Reverses the elements of a proper sexp.

(reverse (sexp 1 2 3))   =>  (3 2 1)

Fresh pairs are allocated so any annotations on the input sexp (but not its elements) are lost.

(reverse (quote a::(1 a::2 3)))  => (3 a::2 1)
(reverse (quote a::()))          => ()
(reverse (quote a::null.sexp))   => null.sexp
same procedure
(same left right)

Like ident but sound for numbers. That is, this procedure guarantees equivalence of (unannotated) numbers with the same type, value, and precision, while ident does not. In effect, unannotated numbers behave as if they were interned.

As with ident, values with different annotations are never same.

(same 1 (quote a::1))                   --> false
(same 2 (+ 1 1))                        --> true
(let [(v 2)] (same v v))                --> true
(same 10600439 10600439)                --> true

(same (quote a::"hi") (quote a::"hi"))  --> // unspecified
same_size procedure
(same_size collection1 collection2)

Returns whether two collections have the same size.

series_to_list procedure
(series_to_list s)

Converts the given series to an immutable list.

Each element of the series must be a single value, so things like (series_to_list {a:1}) will fail.

series_to_sexp procedure
(series_to_sexp s)

Converts the given series to a sexp.

Each element of the series must be a single value, so things like (series_to_sexp {a:1}) will fail.

set syntax
(set var value)

Mutates the given variable, assigning it the value.

sexp procedure
(sexp value ...)

Makes a fresh, immutable sexp containing the given values.

sexp_iterator procedure
(sexp_iterator sexp)

Returns an iterator over the elements of sexp.

size procedure
(size collection)

Returns the number of elements in the collection. The size of null.list (etc.) is zero. If collection is an improper sexp, an exception is thrown.

Warning: Computing the size of an sexp takes linear time, since it must traverse the linked list of pairs to count elements.

string_append procedure
(string_append text ...)

Concatenates the text values (strings or symbols), returning a string. All arguments must be actual strings or symbols, not null.

If no arguments are supplied, the result is "".

string_contains procedure
(string_contains string substring)

Returns true if and only if string contains the substring. Both arguments must be actual strings.

string_ends_with procedure
(string_ends_with string suffix)

Returns true if and only if string ends with suffix. Both arguments must be actual strings.

string_is_lower procedure
(string_is_lower string)

Returns whether string contains only lower-case code points.

A list of lower-case code points can be found online.

string_is_upper procedure
(string_is_upper string)

Returns whether string contains only upper-case code points.

A list of upper-case code points can be found online.

string_join procedure
(string_join separator part ...)

Appends the parts in order into a single string, inserting the separator between adjacent parts. All arguments must be actual strings or symbols.

No separator is added before or after the result. If no parts are supplied, the result is "".

string_replace procedure
(string_replace string from to)

Replaces all occurrences of from with to that occur in string. The string must be a nullable string; null.string is returned as-is. from and to must be actual strings.

Replacement uses literal matching (no regular expressions) and proceeds from the beginning of the string to the end. For example (string_replace "aaa" "aa" "b") will evaluate to "ba".

Replacement when from is an empty string will insert to before, between, and after each character in string. For example (string_replace "aa" "" "b") will evaluate to "babab". If string is also "" a string equal to to is returned.

string_split procedure
(string_split string separator)

Splits string into an immutable list of strings using separator. Both arguments must be actual strings.

Returns an empty list when string is an empty string.

DEPRECATED where separator is a regular expression. That behavior was unintentional, and in conflict with this library's design goal to have no dependency on the Java language or library.

  • Callers needing to split based on regular expressions should use regexp_split from the FusionJavaRegexp package, being careful to adapt code to that method's different argument order, result type (sexp instead of immutable list), and edge cases around leading matches. Test your code thoroughly.
  • Callers needing separators that are escaped to avoid being regular expressions should use string_split_noregexp until the regexp behavior is removed from this procedure. For example, replace:

    (string_split txt "\\.")
    

    with:

    (require "/fusion/experimental/string")
    (string_split_noregexp txt ".")
    
string_starts_with procedure
(string_starts_with string prefix)

Returns true if and only if string begins with prefix. Both arguments must be actual strings.

string_to_int procedure
(string_to_int string)

Converts a string to an int. The string must contain an optional minus sign ("-" aka "\x2D") followed by one or more ASCII digits. Returns null.int when given null.string. An exception is raised if the string is of invalid format.

string_to_lower procedure
(string_to_lower string)

Converts all the characters in a string to lower-case letters.

string_to_symbol procedure
(string_to_symbol string)

Converts a string to a symbol with the same text. Returns null.symbol when given null.string.

string_to_timestamp procedure
(string_to_timestamp string)

Converts a string to a timestamp, recognizing (only) Ion formatted data. Returns null.timestamp when given null.string.

(string_to_timestamp null.string)        ==> null.timestamp
(string_to_timestamp "2013-11-13T")      ==> 2013-11-13
(string_to_timestamp "null.timestamp")   ==> ERROR
string_to_upper procedure
(string_to_upper string)

Converts all the characters in a string to upper-case letters.

struct procedure
(struct name value ... ...)

Constructs an immutable, non-null struct from alternating strings and values. Each name is a non-empty string or symbol denoting a field name, and the following value is the field's value. Names may be repeated to produce repeated (multi-mapped) fields.

struct_do procedure
(struct_do proc struct)

Iterates the fields of struct for side-effects, applying proc to each name/value field. Returns struct. The proc must accept two arguments, a field name symbol and a value; any results from applying the procedure are ignored.

See also: do

struct_iterator procedure
(struct_iterator struct)

Returns an iterator over the content of struct. Calls to iterator_next will return two results representing a single field: the field's name (as a symbol) and the field's value.

(define (show struct)
  (let [(iter (struct_iterator struct))]
    (let loop []
      (when (iterator_has_next iter)
        (let_values [((k v) (iterator_next iter))]
          (displayln k " --> " v)
          (loop))))))
(show {foo:"bar", hello:"goodbye", yes:false})

This code displays:

yes --> false
hello --> goodbye
foo --> bar
struct_merge procedure
(struct_merge struct1 struct2)

Returns a struct that has all the name-value elements of both arguments. This will result in repeated fields if the names overlap or if one of the arguments has repeats. The result has the same type as the first argument.

(struct_merge {a:1} {a:1}) ==> {a:1, a:1}
(struct_merge {a:1} {b:2}) ==> {a:1, b:2}
struct_unzip procedure
(struct_unzip struct)

Deconstructs a struct and returns two values: a list of field names (as symbols) and a list of associated values. This is the inverse of struct_zip.

(let_values [((keys vals) (struct_unzip {a:1, b:2}))]
  (struct_zip keys (map - vals)))
=>
{b:-2,a:-1}

This procedure returns multiple results, not a pair or sequence, so it must be called from a context that expects that, like a let_values clause with two bound identifiers.

struct_zip procedure
(struct_zip names values)

Constructs an immutable struct from a list of field names and a list of values. If the lists have unequal lengths, only the first n elements will be used where n is the shorter length.

The names must be non-empty strings or symbols.

(struct_zip ["f", "g"] [1, 2])  => {f:1,g:2}
(struct_zip ["f", "f"] [1, 2])  => {f:1,f:2}
(struct_zip ["f"] [1, 2])       => {f:1}
subseq procedure
(subseq seq from to)

Returns a sequence holding the elements of the non-null sequence seq between positions from and to. The following precondition applies:

0 <= from <= to <= (size seq)

The result may share structure with seq and has the same type as seq.

symbol_append procedure
(symbol_append text ...)

Concatenates the text values (strings or symbols), returning a symbol. All arguments must be actual strings or symbols, not null.

If no arguments are supplied, the result is "".

symbol_to_string procedure
(symbol_to_string symbol)

Converts a symbol to a string with the same text. Returns null.string when given null.symbol.

tail procedure
(tail sexp)

Returns the elements after the first element of sexp. If sexp is a pair, the result is its tail slot. If sexp isn't a pair (that is, it's zero-length or null.sexp), the result is void.

text_to_string procedure
(text_to_string t)

Normalizes a text value (string or symbol) to a string. Annotations are preserved and null.symbol is converted to null.string.

thunk syntax
(thunk body ...+)

Returns a zero-argument procedure that evaluates the body forms. Equivalent to (lambda () body ...).

timestamp procedure
(timestamp year month? day? hour? minute? second? offset?)

Returns a timestamp representing a specified point in time.

The year is required, and other fields can be added in increasing precision. Acceptable combinations of arguments being present or absent align with the combinations of fields allowed by Ion timestamps. Optional arguments that are not present are equivalent to being void.

  • When present, month must be an actual integer.
  • When present, day must be an actual integer and month must be present.
  • When either is present, hour and minute must both be actual integers, and month and day must be present.
  • When present, second must be an actual integer or decimal, and all preceding arguments must be present.
  • When present, offset must be an actual integer denoting the minutes of local offset; void denotes the unknown local offset -00:00. The offset is ignored when the hour and minutes are not provided.

For example:

(timestamp 2016)                       ==> 2016T
(timestamp 2016 7)                     ==> 2016-07T
(timestamp 2016 7 1)                   ==> 2016-07-01
(timestamp 2016 7 1 9 5)               ==> 2016-07-01T09:05-00:00
(timestamp 2016 7 1 9 5 (void) -420)   ==> 2016-07-01T09:05-07:00
(timestamp 2016 7 1 9 5 6. 0)          ==> 2016-07-01T09:05:06+00:00
(timestamp 2016 7 1 9 5 6. (void))     ==> 2016-07-01T09:05:06-00:00
(timestamp 2016 7 1 9 5 6.123)         ==> 2016-07-01T09:05:06.123-00:00
timestamp_at_day procedure
(timestamp_at_day ts)

Returns a timestamp that represents the same point-in-time as ts, with precision DAY.

timestamp_at_minute procedure
(timestamp_at_minute ts)

Returns a timestamp that represents the same point-in-time as ts, with precision MINUTE. Local offset is preserved.

timestamp_at_month procedure
(timestamp_at_month ts)

Returns a timestamp that represents the same point-in-time as ts, with precision MONTH.

timestamp_at_second procedure
(timestamp_at_second ts)

Returns a timestamp that represents the same point-in-time as ts, with precision SECOND. Local offset is preserved.

timestamp_at_year procedure
(timestamp_at_year ts)

Returns a timestamp that represents the same point-in-time as ts, with precision YEAR.

timestamp_day procedure
(timestamp_day ts)

Returns the day of ts in its local time if its precision is DAY or finer, returns void otherwise.

timestamp_hour procedure
(timestamp_hour ts)

Returns the hour in the day of ts in its local time if its precision is MINUTE or finer, returns void otherwise.

timestamp_minute procedure
(timestamp_minute ts)

Returns the number of minutes past the hour of ts in its local time if its precision is MINUTE or finer, returns void otherwise.

timestamp_month procedure
(timestamp_month ts)

Returns the month of ts in its local time if its precision is MONTH or finer, returns void otherwise.

timestamp_now procedure
(timestamp_now)

Returns a timestamp representing "now". At present the local offset is unspecified, but that may change in the future.

timestamp_offset procedure
(timestamp_offset ts)

Returns the local offset of ts as an integer in minutes if its offset is known, returns void otherwise.

timestamp_put_offset procedure
(timestamp_put_offset ts offset)

Returns a timestamp that has the same time fields (year, month, ...) as ts, with local offset equal to offset minutes. The result may represent a point-in-time different from ts. offset must have magnitude less than 1440 (24 hours).

timestamp_second procedure
(timestamp_second ts)

Returns the number of seconds past the minute in ts in its local time if its precision is SECOND, returns void otherwise.

timestamp_to_epoch_millis procedure
(timestamp_to_epoch_millis timestamp)

Given a non-null timestamp, returns the same point in time represented as the number of milliseconds since 1970-01-01T00:00Z. The result is a decimal.

timestamp_to_string procedure
(timestamp_to_string timestamp)

Converts a timestamp to a string in Ion format. Returns null.string when given null.timestamp.

(timestamp_to_string null.timestamp)   ==> null.string
(timestamp_to_string 2013-11-13T)      ==> "2013-11-13"
timestamp_with_offset procedure
(timestamp_with_offset ts offset)

Returns a timestamp at the same point-in-time as ts, but with local offset equal to offset minutes. The returned timestamp may have different time fields to maintain the same point-in-time. Expects ts to have precision MINUTE or finer.

timestamp_year procedure
(timestamp_year ts)

Returns the year of ts in its local time.

type_annotations procedure
(type_annotations value)

DEPRECATED as of Fusion R20; renamed to annotations.

unless syntax
(unless test body ...)

Evaluates the test, and if it is not truthy, evaluates the body forms left to right. The last body is in tail position, and its result is the result of the entire form. If the body isn't evaluated, the result is void.

A companion form is when.

unquote syntax
(unquote expr)

Used as an escape within a quasiquote form; not valid in any other context.

value_iterator procedure
(value_iterator value)

Returns an iterator that produces value as its only element.

values procedure
(values value ...)

Produces multiple results, returning the zero or more values. Usually used in conjuction with let_values to bind the results to names.

void procedure
(void arg ...)

Returns the singular void value, ignoring all args.

when syntax
(when test body ...)

Evaluates the test, and if it is truthy, evaluates the body forms left to right. The last body is in tail position, and its result is the result of the entire form. If the body isn't evaluated, the result is void.

A companion form is unless.

with_handlers syntax
(with_handlers ((pred_expr handler_expr) ...) body ...+)

Evaluates each pred_expr (predicate) and handler_expr (handler) in order, and then the body forms. The predicate and handler expressions must each return a procedure that accepts one argument: a raised exception value.

If no exceptions are raised during evaluation of the body, then the result of the with_handlers form is the result of the last body form.

If an exception is raised, then each predicate is applied to the exception value. Once a predicate returns a truthy value, then the corresponding handler is applied to the exception, and the handler's result becomes the result of the entire with_handlers form. If the exception is not matched by any predicate, then it is re-raised to the continuation of the with_handlers expression.

Most code should avoid using catch-all predicates like (lambda (x) true) which match exceptions that should generally not be handled by application code. In particular, it will catch non-error_exn exceptions like interrupts, which should pass through unhindered. See the Racket Guide on Exceptions for more details.

with_ion_from_file procedure
(with_ion_from_file path thunk)

Opens the file at path and uses it as the current Ion input port while applying the thunk. The file is closed when the thunk returns (normally or abnormally).

The path must be a non-empty string denoting the file to read. If the path is relative, it is resolved against current_directory. The thunk must be a procedure that accepts zero arguments.

A common use of this procedure is to read the top-level Ion values from a file into a list:

(with_ion_from_file "path/to/file.ion"
  (|| (series_to_list (in_port))))

For other idioms, see /fusion/io.

with_ion_from_lob procedure
(with_ion_from_lob lob thunk)

Uses the content of lob (a blob or clob) as the current Ion input port while applying the thunk.

The lob must be non-null and may contain Ion text or binary data. The thunk must be a procedure that accepts zero arguments.

A common use of this procedure is to read a single Ion value from the data:

(with_ion_from_lob {{"[only_me]"}} read)   --> [only_me]

A common use of this procedure is to read the top-level Ion values from a lob into a list:

(with_ion_from_lob {{"[first] 2"}}   // Reading from a clob
  (|| (series_to_list (in_port))))
=>
[[first], 2]

For other idioms, see /fusion/io.

with_ion_from_string procedure
(with_ion_from_string string thunk)

Uses the content of string as the current Ion input port while applying the thunk.

The string must be non-null and must contain Ion text data. The thunk must be a procedure that accepts zero arguments.

A common use of this procedure is to read a single Ion value from the data:

(with_ion_from_string "123" read)   --> 123

This leverages the fact that read accepts zero arguments and consumes the current Ion input port. Note that this is likely to be more lenient than you wish, since the input is treated as a full Ion document:

(with_ion_from_string "$ion_1_0 123 /* ignored */" read)  --> 123

If more than one value is expected, you can read them all into a list:

(with_ion_from_string "1 k {a:false}"
  (|| (series_to_list (in_port))))
=>
[1, k, {a:false}]

For other idioms, see /fusion/io.

write procedure
(write value)

Outputs a text representation of value to the current output port, following Ion syntax where possible. The result will be unreadable (by the Fusion and Ion readers) if the value contains any non-Ionizable data like closures. Contrast this with ionize, which throws an exception in such cases.

writeln procedure
(writeln value)

Writes the value, then a newline.

| syntax
(| arg ... | body ...+)

A more concise alternative to lambda. The | (pipe) identifier is followed by zero or more argument identifiers, then another pipe, then the body of the procedure.

The translation from | to lambda is straightforward:

(| x ... | body ...) -> (lambda (x ...) body ...)
(| | body ...) -> (lambda () body ...)

Note that (| | body) and (|| body) generate identical code, but they are technically not the same syntactic form. The Ion grammar specifies that || is a single, two-character symbol, so the latter expression uses the form named ||, which creates a no-argument procedure.

|| syntax
(|| body ...+)

Returns a zero-argument procedure that evaluates the body forms. Equivalent to (lambda () body ...).

See also |.

#%top syntax
('#%top' id)

References a top-level definition for symbol id, skipping over any surrounding local bindings. Within a module, id must be defined within the module and not locally.

As suggested by the awkward name, this form is rarely needed by application code and is primarily an artifact of the macro-expansion process.