range
evaluates an expression for each element of a vector/object, effectively
allowing to loop over them. Note that this is not intended to actually modify
the source vector/object, for those tasks map
and
filter
should be used instead. range
is less often used,
especially with over functions that would have side effects or to build up
counters/sums.
range
returns the value of the last evalauted expression. Note that since
objects are iterated in effectively random order, one should not rely on the
return value of range
when ranging over objects.
(range ["foo" "bar"] [value] (print $value))
➜nil
(range {a "b" c "d"} [key value] (print $key))
➜nil
source
is an arbitrary expression.params
is a vector describing the desired loop variable name(s).expr
is an arbitrary expression.
range
evaluates the source argument and coalesces it to a vector or object,
with vectors being preferred. If either of these operations fail, an error is
returned. The naming vector params
then allows to set the index/value (for
vectors) or key/value (for objects) as variables, which can then be used in the
expression expr
, for example:
(range .data [v] (set! .data.users[$v] = "foo"))
(range .data [v] (set! $var (+ (try $var 0) 1)))
params
must be a vector containing one or two identifiers. If a single
identifier is given, it's the variable name for the value. If two identifiers
are given, the first is used for the index/key, the second is used for the value.
expr
can then be any expression. Just like the other form, source
is
evaluated and coalesced to vector/object and the expression is then applied to
each element.
range
evaluates all expressions using a shared context, so it's possible for
the expressions to share variables.