x-lang

← Index

x/core/fn

Higher-order function combinators and callable reflection, homed on the Fn class.

Function combinators as static methods: (Fn compose f g), (Fn flip f), (Fn tap f).

Reflection on a callable: (Fn label f) says which callable it is, (Fn params f), (Fn body f) and (Fn env f) read what a closure or an operative is made of.

apply

Apply f to a list of arguments, with any leading arguments spliced in front: (apply f a b (list c d)) calls f with (a b c d). A closure, a primitive or an operative is applied by the engine; a wrapped combiner, (wrap c), is applied as c; any other value is applied through its type’s call handler, the way (v args…) calls it, and a value with no handler raises a type error.

Parameters:

Returns: ANY — What f answers

Examples:

(apply + (list 1 2)) => 3
(apply + 1 2 (list 3 4)) => 10
(apply (Vector of 1 2 3) (list 1)) => 2
(apply (wrap (op (a) e a)) (list 5)) => 5
(guard (e (Err label e)) (apply () (list 1))) => 'type

Class Fn

(Fn identity x)

Return the given value unchanged.

Parameters:

Returns: ANY — The input value unchanged

Examples:

(Fn identity 5) => 5

(Fn const x)

Return a function that always returns x, ignoring its argument.

Parameters:

Returns: CALLABLE — A function that always returns x

Examples:

((Fn const 7) 1) => 7

(Fn compose f g)

Right-to-left composition: (Fn compose f g) applies g then f.

Parameters:

Returns: CALLABLE — Composed function f(g(x))

Examples:

((Fn compose (method-ref Num inc) (method-ref Num inc)) 1) => 3

(Fn pipe f g)

Left-to-right composition: (Fn pipe f g) applies f then g.

Parameters:

Returns: CALLABLE — Piped function g(f(x))

Examples:

((Fn pipe (method-ref Num inc) (fn (_ x) (* x 10))) 1) => 20

(Fn curry f x)

Partially apply a binary function by fixing its first argument.

Parameters:

Returns: CALLABLE — Function awaiting one argument

Examples:

((Fn curry - 10) 3) => 7

(Fn flip f)

Return a function that calls f with its two arguments reversed.

Parameters:

Returns: CALLABLE — Function with reversed argument order

Examples:

((Fn flip -) 10 3) => -7

(Fn tap f)

Call f on the argument for side effects, then return the argument.

Parameters:

Returns: CALLABLE — Function applying f then returning its argument

Examples:

((Fn tap (method-ref Num inc)) 5) => 5

(Fn default-to d x)

Return x if non-nil, otherwise return the default d.

Parameters:

Returns: ANY — x if non-nil, otherwise d

Examples:

(Fn default-to 0 ()) => 0
(Fn default-to 0 5) => 5

(Fn until pred f x)

Repeatedly apply f to x until pred is satisfied, then return the value.

Parameters:

Returns: ANY — First value satisfying pred

Examples:

(Fn until (fn (_ x) (> x 100)) (fn (_ x) (* x 2)) 1) => 128

(Fn complement pred)

Return a function that negates a predicate.

Parameters:

Returns: CALLABLE — Negated predicate

Examples:

((Fn complement null?) 5) => #t

(Fn partial f . bound)

Partially apply a function with leading arguments.

Parameters:

Returns: CALLABLE — Partially applied function

Examples:

((Fn partial + 1 2) 3) => 6

(Fn juxt . fns)

Create a function that applies multiple functions and collects results.

Parameters:

Returns: CALLABLE — Juxtaposed function

Examples:

((Fn juxt (method-ref Num inc) (method-ref Num dec)) 5) => (6 4)

(Fn both f g)

Combine two predicates with AND.

Parameters:

Returns: CALLABLE — Combined predicate

Examples:

((Fn both (fn (_ x) (> x 0)) (fn (_ x) (< x 10))) 5) => #t

(Fn either f g)

Combine two predicates with OR.

Parameters:

Returns: CALLABLE — Combined predicate

Examples:

((Fn either (fn (_ x) (< x 0)) (fn (_ x) (> x 10))) 20) => #t

(Fn all-pass preds)

Return a predicate that passes when all predicates pass.

Parameters:

Returns: CALLABLE — Combined predicate

Examples:

((Fn all-pass (list (fn (_ x) (> x 0)) (fn (_ x) (< x 10)))) 5) => #t

(Fn any-pass preds)

Return a predicate that passes when any predicate passes.

Parameters:

Returns: CALLABLE — Combined predicate

Examples:

((Fn any-pass (list (fn (_ x) (< x 0)) (fn (_ x) (> x 10)))) 20) => #t

(Fn apply-values! takes?)

Say which primitives apply hands its values as they are. apply quotes each value for a primitive, which evaluates what it is given; a primitive that is handed values by the engine’s apply routine, as a function compiled by x/tool/fn-compile is, must not have them quoted. One answer is kept, the last given.

Parameters:

Returns: NIL — nil

(Fn label f)

Which callable f is: ‘fn for a closure made by fn, ‘op for an operative made by op, ‘wrap for a wrapped combiner made by wrap, ‘prim for an engine primitive, and () for anything else, including a value that is callable only through its type’s call handler.

Parameters:

Returns: SYMBOL — ‘fn, ‘op, ‘wrap or ‘prim, or () for a value that is none of them

Examples:

(Fn label (fn (_ x) x)) => 'fn
(Fn label (op (x) e x)) => 'op
(Fn label (wrap (op (x) e x))) => 'wrap
(Fn label first) => 'prim
(null? (Fn label 42)) => #t

(Fn %state f)

The state of a closure or an operative, slot 1, or () for any other value.

Examples:

(first (Fn %state (fn (_ x) x))) => ('_ 'x)

(Fn params f)

The parameter list of f as written: a closure’s formals, self first, or an operative’s; a single symbol for a variadic closure. () for a wrapped combiner, a primitive, or a value that is not a callable.

Parameters:

Returns: ANY — The parameter list as written, a symbol, or ()

Examples:

(Fn params (fn (self a b) (+ a b))) => ('self 'a 'b)
(Fn params (fn args args)) => 'args
(Fn params (op (x) e x)) => ('x)

(Fn body f)

The body forms of f as written, in order. () for a wrapped combiner, a primitive, or a value that is not a callable.

Parameters:

Returns: LIST — The body forms, or ()

Examples:

(Fn body (fn (_ n) (+ n 1) (* n 2))) => (('+ 'n 1) ('* 'n 2))
(Fn body (op (x) e (eval x e))) => (('eval 'x 'e))

(Fn env f)

The environment f was made in and resolves its free names through: one pair (bindings . parent), where a frame’s bindings are an alist of (name . value) and the root’s and a module’s are a tree. () for a wrapped combiner, a primitive, or a value that is not a callable. Do not write the result: every environment’s chain ends at the root, which binds closures whose environment is the root again, so write never finishes. Ask Env names of it, and Env parent for the frame outside it.

Parameters:

Returns: ANY — An environment, or ()

Examples:

(eval 'k (Fn env ((fn (_ k) (fn (_) k)) 7))) => 7