for
iterate over items or stream of items
<for> = for [<decl>[, <decl>]] [in <expr>] <body>
<body> = { <statements> }
| if <expr> <body>
| [pass]
| <command>
Input
for is very versatile and can work in two input
modes:
for-in, when a list, a map or any other container is specified, for examplefor $i in [1, 2, 3] {}.stream-for,forconsumes input stream of items, e.gput 1 2 3 | for $i {}will be called 3 times.
for defines a new variable or reuses an existing one, if
it's already present in the parent scope. This is somewhat consistent
with := behavior, except := requires at least
one new variable to be defined. Each for has its own scope,
new variables are not visible outside of this scope.
for-in allows to specify two variables, in this case the
first one would contain a key or an index, and the second will be an
item itself. stream-for supports only one.
for each item in $list, assign it to $item
and run body |
|
| stream dictionary values (keys are ignored) | |
| stream dictionary keys (values are ignored) | |
| make first 10 powers of 2 | |
| print file sizes in the current directory | |
consume function's input stream using >>, threat
it like filenames and create a map with stat information
for each file |
|
Filtering
It's possible to iterate only on items that match a predicate using
if syntax. Items, that don't match the predicate, are
discarded. It's possible to specify if multiple times.
There's no else part.
| print a first few even numbers | |
| output files, whose file name is longer 20 symbols | |
Pass Through
Instead of using { put $item } as a body, it's possible
to use pass or to to not provide body at all.
| output a first few even numbers | for $i in (range 10) if $i%2 == 0 |
| output file names, that are longer than 20 symbols | ls | for $f if (len $f) > 20 |
| save file names, that are longer than 20 symbols, in a file | |
Pattern Matching
String and list pattern
matching can be used inside for's declarations.
| convert all jpg files to png | |
apply :colons formatter before assigning to a
variable |
|
Direct Commands
A single command can be written without using { }. This
should feel similar to xargs -l1, but with variables
specified explicitly.
run uptime on all hosts via ssh |
cat hosts.txt | for $h ssh $h uptime |
| convert all jpg files to png | |
Discussion: this is, perhaps, too dense. Even if it's okay syntactically, it is maybe worth to put an arrow before command:
cat hosts.txt | for $h -> ssh $h uptime