Skip to content

Instantly share code, notes, and snippets.

@sogaiu
Last active July 26, 2026 07:02
Show Gist options
  • Select an option

  • Save sogaiu/264c42bd4a2f04f2c55472244339051e to your computer and use it in GitHub Desktop.

Select an option

Save sogaiu/264c42bd4a2f04f2c55472244339051e to your computer and use it in GitHub Desktop.
# for fibers:
#
# * `resume` / `next` mutate fiber state
# * `get` / `in` only retrieve fiber's "last value"
# may not completely consume fiber
(comment
``
(next ds &opt key)
Gets the next key in a data structure. Can be used to iterate
through the keys of a data structure in an unspecified order. Keys
are guaranteed to be seen only once per iteration if the data
structure is not mutated during iteration. If key is nil, next
returns the first key. If next returns nil, there are no more keys
to iterate through.
``
# "data structure"
(do
(def f (coro (yield :fun) (yield :end)))
(def k1 (next f nil))
(def k2 (next f k1))
(def k3 (next f k2))
[[k1 k2 k3] (fiber/can-resume? f)])
# =>
[[0 0 nil] false]
``
(get ds key &opt dflt)
Get the value mapped to key in data structure ds, and return dflt
or nil if not found. Similar to in, but will not throw an error if
the key is invalid for the data structure unless the data structure
is an abstract type. In that case, the abstract type getter may
throw an error.
``
# "data structure"
(do
(def f (coro (yield :smile) (yield :wink)))
(resume f)
(def res-1 (get f 0))
(resume f)
(def res-2 (get f 0))
(resume f)
(def res-3 (get f 0))
[[res-1 res-2 res-3] (fiber/can-resume? f)])
# =>
[[:smile :wink nil] false]
``
(first xs)
Get the first element from an indexed data structure.
``
# "indexed data structure"
# depends on get
(do
(def f (coro (yield :hello) (yield :bye)))
(resume f)
(def res-1 (first f))
(resume f)
(def res-2 (first f))
(resume f)
(def res-3 (first f))
[[res-1 res-2 res-3] (fiber/can-resume? f)])
# =>
[[:hello :bye nil] false]
``
(in ds key &opt dflt)
Get value in ds at key, works on associative data structures.
Arrays, tuples, tables, structs, strings, symbols, and buffers are
all associative and can be used. Arrays, tuples, strings, buffers,
and symbols must use integer keys that are in bounds or an error is
raised. Structs and tables can take any value as a key except nil
and will return nil or dflt if not found.
``
# "associative data structure"
(do
(def f (coro (yield 11) (yield 8)))
(resume f)
(def res-1 (in f 0))
(resume f)
(def res-2 (in f 0))
(resume f)
(def res-3 (in f 0))
[[res-1 res-2 res-3] (fiber/can-resume? f)])
# =>
[[11 8 nil] false]
``
(get-in ds ks &opt dflt)
Access a value in a nested data structure. Looks into the data
structure via a sequence of keys. If value is not found, and dflt
is provided, returns dflt.
``
# "nested data structure"
# depends on get / in
(do
(def f (coro (yield [:a :b])))
(resume f)
(def res (get-in f [0 1]))
[res (fiber/can-resume? f)])
# =>
[:b true]
``
(has-value? ds value)
Find the first key associated with a value x in a data structure,
acting like a reverse lookup. Will not look at table prototypes.
Returns dflt if not found.
``
# "data structure"
# depends on index-of
(do
(def f (coro (yield :breathe) (yield :smile) (yield :relax)))
[[(has-value? f :smile) (has-value? f :relax) (has-value? f :breathe)]
(fiber/can-resume? f)])
# =>
[[true true false] false]
)
# completely consumes fiber
(comment
``
(seq head & body)
Similar to loop, but accumulates the loop body into an array and
returns that. See loop for details.
``
# from loop's docstring
``
* :in -- iterate over the values in a data structure or fiber.
``
# "data structure"
# depends on in
(do
(def f (coro (yield :gentle) (yield :breeze)))
(def res (seq [v :in f] v))
[res (fiber/can-resume? f)])
# =>
[@[:gentle :breeze] false]
``
(all pred ind & inds)
Returns true if applying pred to every value in a data structure
ind results in only truthy values, but only if no inds are
provided. Multiple data structures can be handled if each inds is a
data structure and pred is a function of arity one more than the
number of inds. Returns the first falsey result encountered. Note
that pred is only called as many times as the length of the
shortest of ind and each of inds. If ind or any of inds are empty,
returns true.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield 1) (yield 3)))
(def res (all odd? f))
[res (fiber/can-resume? f)])
# =>
[true false]
``
(count pred ind & inds)
Count the number of values in a data structure ind for which
applying pred yields a truthy value, but only if no inds are
provided. Multiple data structures can be handled if each inds is a
data structure and pred is a function of arity one more than the
number of inds. Note that pred is only applied to values at indices
up to the largest index of the shortest of ind and each of inds.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield 0) (yield 1) (yield 2)))
(def res (count even? f))
[res (fiber/can-resume? f)])
# =>
[2 false]
``
(keep pred ind & inds)
Given a predicate pred, return a new array containing the truthy
results of applying pred to each value in the data structure ind,
but only if no inds are provided. Multiple data structures can be
handled if each inds is a data structure and pred is a function of
arity one more than the number of inds. The resulting array has a
length that is no longer than the shortest of ind and each of inds.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield -2) (yield 0) (yield 11) (yield 28)))
(def res (keep |(when (pos? $) $) f))
[res (fiber/can-resume? f)])
# =>
[@[11 28] false]
``
(map f ind & inds)
Map a function f over every value in a data structure ind and
return an array of results, but only if no inds are provided.
Multiple data structures can be handled if each inds is a data
structure and f is a function of arity one more than the number of
inds. The resulting array has a length that is the shortest of ind
and each of inds.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield 1) (yield 2)))
(def res (map inc f))
[res (fiber/can-resume? f)])
# =>
[@[2 3] false]
``
(mapcat f ind & inds)
Map a function f over every value in a data structure ind and use
array/concat to concatenate the results, but only if no inds are
provided. Multiple data structures can be handled if each inds is a
data structure and f is a function of arity one more than the
number of inds. Note that f is only applied to values at indices up
to the largest index of the shortest of ind and each of inds.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield [0 1]) (yield [2 8])))
(def res (mapcat identity f))
[res (fiber/can-resume? f)])
# =>
[@[0 1 2 8] false]
``
(some pred ind & inds)
Returns nil if applying pred to every value in a data structure ind
results in only falsey values, but only if no inds are provided.
Multiple data structures can be handled if each inds is a data
structure and pred is a function of arity one more than the number
of inds. Returns the first truthy result encountered. Note that
pred is only called as many times as the length of the shortest of
ind and each of inds. If ind or any of inds are empty, returns nil.
``
# "data structure"
# depends on map-template -> in / next
(do
(def f (coro (yield 1) (yield 2)))
(def res (some pos? f))
[res (fiber/can-resume? f)])
# =>
[true true]
``
(partition-by f ind)
Partition elements of a sequential data structure by a
representative function f. Partitions split when (f x) changes
values when iterating to the next element x of ind. Returns a new
array of arrays.
``
# "sequential data structure"
# depends on each -> each-template -> in / next
(do
(def f (coro (yield 2) (yield 0) (yield 5) (yield 0)))
(def res (partition-by pos? f))
[res (fiber/can-resume? f)])
# =>
[@[@[2] @[0] @[5] @[0]] false]
``
(frequencies ind)
Get the number of occurrences of each value in an indexed data
structure.
``
# "indexed data structure"
# depends on each -> each-template -> in / next
(do
(def f (coro (yield 1) (yield 2)))
(def res (frequencies f))
[res (fiber/can-resume? f)])
# =>
[@{1 1 2 1} false]
``
(invert ds)
Given an associative data structure ds, returns a new table where
the keys of ds are the values, and the values are the keys. If
multiple keys in ds are mapped to the same value, only one of those
values will become a key in the returned table.
``
# "associative data structure"
# depends on loop -> in / next
(do
(def f (coro (yield :ant) (yield :bee)))
(def res (invert f))
[res (fiber/can-resume? f)])
# =>
[@{:ant 0 :bee 0} false]
``
(values x)
Get the values of an associative data structure.
``
# "associative data structure"
# depends on seq -> loop -> in / next
(do
(def f (coro (yield :fine) (yield :powder)))
(def res (values f))
[res (fiber/can-resume? f)])
# =>
[@[:fine :powder] false]
``
(partition n ind)
Partition an indexed data structure ind into tuples of size n.
Returns a new array.
``
# "indexed data structure"
# depends on values
(do
(def f (coro (yield 2) (yield 3) (yield 5) (yield 7)))
(def res (partition 2 f))
[res (fiber/can-resume? f)])
# =>
[@[[2 3] [5 7]] false]
)
# mostly not too useful, but doesn't error
(comment
``
(index-of x ind &opt dflt)
Find the first key associated with a value x in a data structure,
acting like a reverse lookup. Will not look at table prototypes.
Returns dflt if not found.
``
# XXX: data structure
# depends on next / in
# XXX: not that useful result for end user, but is for has-value?
(do
(def f (coro (yield 11) (yield 8)))
(def res-1 (index-of 8 f :default))
(def res-2 (index-of 11 f :default))
[[res-1 res-2] (fiber/can-resume? f)])
# =>
[[0 :default] false]
``
(has-key? ds key)
Check if a data structure ds contains the key key.
``
# XXX: data strucutre
# XXX: a fiber only ever has at most one key and if it does,
# the key's value is always 0
(do
(def f (coro (yield :smile) (yield :wink)))
(resume f)
(def res-1 (has-key? f 0))
(resume f)
(def res-2 (has-key? f 0))
(resume f)
(def res-3 (has-key? f 0))
[res-1 res-2 res-3])
# =>
[true true false]
``
(keys x)
Get the keys of an associative data structure.
``
# XXX: associative data structure
# XXX: not that useful result - just use count + alpha instead
(keys (coro (yield :fox) (yield :elephant)))
# =>
@[0 0]
``
(pairs x)
Get the key-value pairs of an associative data structure.
``
# XXX: associative data structure
# XXX: not that useful result - just use values instead
(pairs (coro (yield :ant) (yield :bee)))
# =>
@[[0 :ant] [0 :bee]]
# from loop's docstring
``
* :keys -- iterate over the keys in a data structure.
* :pairs -- iterate over the key-value pairs as tuples in a data
structure.
* :in -- iterate over the values in a data structure or fiber.
``
# XXX: data structure
# XXX: not that useful result - just use count + alpha instead
(seq [k :keys (coro (yield :gentle) (yield :breeze))]
k)
# =>
@[0 0]
# from loop's docstring
``
* :pairs -- iterate over the key-value pairs as tuples in a data
structure.
``
# XXX: data structure
# XXX: not that useful - just use :in
(seq [p :pairs (coro (yield :gentle) (yield :breeze))]
p)
# =>
@[[0 :gentle] [0 :breeze]]
# XXX: data structure
# :keys, :pairs
#(loop)
#(catseq)
#(tabseq)
``
(walk f form)
Iterate over the values in ast and apply f to them. Collect the
results in a data structure. If ast is not a table, struct, array,
or tuple, returns form.
``
# XXX: data structure
# form is passed through in walk
# XXX: nothing happens
(do
(def f (coro (yield :alice) (yield :bob)))
(def res (walk identity f))
[(= f res) (fiber/can-resume? f)])
# =>
[true true]
``
(prewalk f form)
Similar to postwalk, but do pre-order traversal.
``
# XXX: data structure
# depends on walk
# XXX: nothing happens
(do
(def f (coro (yield :ice) (yield :steam)))
(def res (postwalk identity f))
[(= f res) (fiber/can-resume? f)])
# =>
[true true]
``
(postwalk f form)
Do a post-order traversal of a data structure and call (f x) on
every visitation.
``
# XXX: data structure (by reference to postwalk's docstring)
# depends on walk
# XXX: nothing happens
(do
(def f (coro (yield :ice) (yield :steam)))
(def res (prewalk identity f))
[(= f res) (fiber/can-resume? f)])
# =>
[true true]
)
# errors for various reasons
(comment
``
(length ds)
Returns the length or count of a data structure in constant time as
an integer. For structs and tables, returns the number of key-value
pairs in the data structure.
``
# XXX: data structure
# XXX: fibers don't support `length`
(-> (length (coro (yield 2) (yield 3) (yield 5)))
protect
first)
# =>
false
``
(last xs)
Get the last element from an indexed data structure.
``
# XXX: indexed data structure
# XXX: depends on length
(-> (last (coro (yield :head) (yield :tail)))
protect
first)
# =>
false
``
(put ds key value)
Associate a key with a value in any mutable associative data
structure. Indexed data structures (arrays and buffers) only accept
non-negative integer keys, and will expand if an out of bounds
value is provided. In an array, extra space will be filled with
nils, and in a buffer, extra space will be filled with 0 bytes. In
a table, putting a key that is contained in the table prototype
will hide the association defined by the prototype, but will not
mutate the prototype table. Putting a value nil into a table will
remove the key from the table. Returns the data structure ds.
``
# XXX: mutable associative data structure
# XXX: fibers are not directly settable
(-> (put (coro (yield :value)) 0 :treasure)
protect
first)
# =>
false
``
(put-in ds ks v)
Put a value into a nested data structure ds. Looks into ds via a
sequence of keys. Missing data structures will be replaced with
tables. Returns the modified, original data structure.
``
# XXX: nested data structure
# XXX: fibers are not directly settable
(-> (put-in (coro (yield :value)) [0 0] :treasure)
protect
first)
# =>
false
``
(update ds key func & args)
For a given key in data structure ds, replace its corresponding
value with the result of calling func on that value. If args are
provided, they will be passed along to func as well. Returns ds,
updated.
``
# XXX: data structure
# XXX: fibers are not directly settable
(-> (update (coro (yield :value)) 0 string)
protect
first)
# =>
false
``
(update-in ds ks f & args)
Update a value in a nested data structure ds. Looks into ds via a
sequence of keys, and replaces the value found there with f applied
to that value. Missing data structures will be replaced with
tables. Returns the modified, original data structure.
``
# XXX: data structure
# XXX: fibers are not directly settable
(-> (update-in (coro (yield :value)) [0 0] string)
protect
first)
# =>
false
``
(slice x &opt start end)
Extract a sub-range of an indexed data structure or byte sequence.
``
# XXX: indexed data structure
# XXX: could theoretically work(?) but doesn't
(-> (slice (coro (yield 1) (yield 2) (yield 3)) 1)
protect
first)
# =>
false
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment