Wiki: Janet

Looping over arguments

(reduce2|[(f $1)(g $1)](dyn :args))
(map|[(f $)(g $)](drop 1(dyn :args)))
(each a(drop 1(dyn :args))(f a)(g a))

each is good when you have multiple statements and/or nested functions, otherwise map/reduce2 is better. reduce2 avoids the first argument, but is slightly longer and you have to use $1 instead $ which evens up after 4 uses.

Indexing

There's a few different ways to get a value from a data structure such as a tuple:

(ds idx)               # Shortest, but no default and errors when out of range
(idx ds)               # The same but with different execution order I guess
(in ds idx default?)   # Has default, still throws error when out of range, so only good for dictionaries
(get ds idx default?)  # Nil/default when out of range

Related, you can use put on arrays/buffers and it will extend it and fill the empty spaces with nils/null bytes.

Conditionals

(if(cond)x y)          # Short circuits, you can leave the false section out to return nil, needs a truthy or (falsey/nil) condition
(and/or cond x)        # Short circuits, multiple conditions
(case n v x default)   # Short circuits, checks specific values, has default
(in{v x}n default)     # Same as case, but no short circuit
({v x n default}n)     # Same again, but with more whitespace to save though using n twice
([x y]n)               # Needs a numeric 0/1 condition