rudus/assets/test_prelude.ld

249 lines
5.8 KiB
Plaintext

& & the very base: know something's type
& fn type {
& "Returns a keyword representing the type of the value passed in."
& (x) -> base :type (x)
& }
& & some helper type functions
& fn coll? {
& "Returns true if a value is a collection: dict, list, tuple, or set."
& (coll as :dict) -> true
& (coll as :list) -> true
& (coll as :tuple) -> true
& & (coll as :set) -> true
& (_) -> false
& }
& fn ordered? {
& "Returns true if a value is an indexed collection: list or tuple."
& (coll as :list) -> true
& (coll as :tuple) -> true
& (coll as :string) -> true
& (_) -> false
& }
& fn assoc? {
& "Returns true if a value is an associative collection: a dict or a pkg."
& (d as :dict) -> true
& (_) -> false
& }
& &&& nil: working with nothing
& fn nil? {
& "Returns true if a value is nil."
& (nil) -> true
& (_) -> false
& }
& fn some? {
& "Returns true if a value is not nil."
& (nil) -> false
& (_) -> true
& }
& fn some {
& "Takes a possibly nil value and a default value. Returns the value if it's not nil, returns the default if it's nil."
& (nil, default) -> default
& (value, _) -> value
& }
& & ...and if two things are the same
& fn eq? {
& "Returns true if all arguments have the same value."
& (x) -> true
& (x, y) -> base :eq? (x, y)
& (x, y, ...zs) -> if eq? (x, y)
& then loop (y, zs) with {
& (a, []) -> eq? (a, x)
& (a, [b, ...cs]) -> if eq? (a, x)
& then recur (b, cs)
& else false
& }
& else false
& }
& &&& true & false: boolean logic (part the first)
& fn bool? {
& "Returns true if a value is of type :boolean."
& (false) -> true
& (true) -> true
& (_) -> false
& }
& fn true? {
& "Returns true if a value is boolean `true`. Useful to distinguish between `true` and anything else."
& (true) -> true
& (_) -> false
& }
& fn false? {
& "Returns `true` if a value is `false`, otherwise returns `false`. Useful to distinguish between `false` and `nil`."
& (false) -> true
& (_) -> false
& }
& fn bool {
& "Returns false if a value is nil or false, otherwise returns true."
& (nil) -> false
& (false) -> false
& (_) -> true
& }
& fn not {
& "Returns false if a value is truthy, true if a value is falsy."
& (nil) -> true
& (false) -> true
& (_) -> false
& }
& & tuples: not a lot you can do with them functionally
& fn tuple? {
& "Returns true if a value is a tuple."
& (tuple as :tuple) -> true
& (_) -> false
& }
& &&& functions: getting things done
& fn fn? {
& "Returns true if an argument is a function."
& (f as :fn) -> true
& (_) -> false
& }
& what we need for some very basic list manipulation
fn first {
"Retrieves the first element of an ordered collection--a tuple or a list. If the collection is empty, returns nil."
([]) -> nil
(()) -> nil
("") -> nil
(xs as :list) -> base :first (xs)
(xs as :tuple) -> base :first (xs)
(str as :string) -> base :slice (str, 0, 1)
}
fn rest {
"Returns all but the first element of a list or tuple, as a list."
([]) -> []
(()) -> ()
(xs as :list) -> base :rest (xs)
(xs as :tuple) -> base :rest (xs)
(str as :string) -> base :rest (str)
}
fn inc {
"Increments a number."
(x as :number) -> base :inc (x)
}
& fn dec {
& "Decrements a number."
& (x as :number) -> base :dec (x)
& }
& fn count {
& "Returns the number of elements in a collection (including string)."
& (xs as :list) -> base :count (xs)
& (xs as :tuple) -> base :count (xs)
& (xs as :dict) -> base :count (xs)
& (xs as :string) -> base :count (xs)
& & (xs as :set) -> base :count (xs)
& }
& fn empty? {
& "Returns true if something is empty. Otherwise returns false (including for things that can't logically be empty, like numbers)."
& ([]) -> true
& (#{}) -> true
& & (s as :set) -> eq? (s, ${})
& (()) -> true
& ("") -> true
& (_) -> false
& }
& fn any? {
& "Returns true if something is not empty, otherwise returns false (including for things that can't be logically full, like numbers)."
& ([...]) -> true
& (#{...}) -> true
& & (s as :set) -> not (empty? (s))
& ((...)) -> true
& (s as :string) -> not (empty? (s))
& (_) -> false
& }
& fn list? {
& "Returns true if the value is a list."
& (l as :list) -> true
& (_) -> false
& }
& fn list {
& "Takes a value and returns it as a list. For values, it simply wraps them in a list. For collections, conversions are as follows. A tuple->list conversion preservers order and length. Unordered collections do not preserve order: sets and dicts don't have predictable or stable ordering in output. Dicts return lists of (key, value) tuples."
& (x) -> base :list (x)
& }
fn append {
"Adds an element to a list."
() -> []
(xs as :list) -> xs
(xs as :list, x) -> base :append (xs, x)
}
fn fold {
"Folds a list."
(f as :fn, []) -> []
(f as :fn, xs as :list) -> fold (f, xs, f ())
(f as :fn, [], root) -> []
(f as :fn, xs as :list, root) -> loop (root, first (xs), rest (xs)) with {
(prev, curr, []) -> f (prev, curr)
(prev, curr, remaining) -> recur (
f (prev, curr)
first (remaining)
rest (remaining)
)
}
}
fn map {
"Maps a function over a list: returns a new list with elements that are the result of applying the function to each element in the original list. E.g., `map ([1, 2, 3], inc) &=> [2, 3, 4]`. With one argument, returns a function that is a mapper over lists; with two, it executes the mapping function right away."
& (f as :fn) -> map (f, _)
& (kw as :keyword) -> map (kw, _)
(f as :fn, xs) -> {
fn mapper (prev, curr) -> append (prev, f (curr))
fold (mapper, xs, [])
}
& (kw as :keyword, xs) -> {
& fn mapper (prev, curr) -> append (prev, kw (curr))
& fold (mapper, xs, [])
& }
}
#{
& type
& coll?
& ordered?
& assoc?
& nil?
& some?
& some
& eq?
& bool?
& true?
& false?
& bool
& not
& tuple?
& fn?
& rest
inc
& dec
& count
& empty?
& any?
& list?
& list
& first
& fold
& append
map
}