One of the big features missing from KRL as a rule language is a foreach
statement that allows looping. Build 351 of KNS (released today) fixes that problem. The thing that kept holding me back was confusion on my part about the best way to add it and how it should work.
The problem was that I wanted, thought KRL needed, more than just looping. I wanted full-blown FLWOR statements (foreach, let, where, order by, result). I realized one day on a bike ride that the entire rule ought to be a FLWOR statement and that meant that the foreach
needed to happen before the rule body executed.
The rule prelude already functions in the capacity of a "let," the rule premise (condition on the action) already functions in the capacity of a "where," and the rule action itself is the "result." Yeah, I left out "order." More on that later.
KRL now allows one or more foreach
clauses to be added to the select
statement like so:
select using "/archives/" setting () foreach [1, 2, 3] setting (x)
The value of x
will be bound to the values 1, 2, and 3 on successive executions of the rule body. KNS optimizes the rule so that declarations in the prelude aren't executed inside the loop unless they depend on the value of the variable (directly or indirectly).
Of course, the array is an expression, so it doesn't have to be an array literal. You could do this:
select using "/archives/" setting () foreach f.pick("$..store") setting (x)
This works fine as long as f
has been declared outside the rule in the global
and the pick
returns an array.
The entire rule body--everything after the select
is executed once for every loop. If the premise is true, an action is produced, so a rule with a foreach
over a three element array would produce three actions if the premise were true each time.
We can't order the array yet. Adding a sort
operator on arrays would do the trick but to do that I need someway to specify the comparison function and KRL doesn't have functions or closures...yet.
Looping has been a long time coming, but I'm excited to see what people do with it. Surprise me!