From 1f17ef3623f1dc9366b9f9264ae3e93fc8e04b66 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Tue, 1 Jul 2014 23:32:44 -0500 Subject: [PATCH] Descrive generators, range() with by to manual --- docs/content/3.manual/manual.yml | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index e21e9bd2..0be5e4b7 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -1697,6 +1697,52 @@ sections: input: '[10,2,5,3]' output: ['20'] + - title: Recursion + body: | + + As described above, `recurse` uses recursion, and any jq + function can be recursive. Tail calls are optmized. + + - title: Generators and iterators + body: | + + Some jq operators and functions are actually generators in + that they can produce zero, one, or more values for each + input, just as one might expect in other programming + languages that have generators. For example, `.[]` + generates all the values in its input (which must be an + array or an object), `range(0; 10)` generates the integers + between 0 and 10, and so on. + + Even the comma operator is a generator, generating first the + values generated by the expression to the left of the comma, + then for each of those, the values generate by the + expression on the right of the comma. + + The `empty` builtin is the generator that produces zero + outputs. The `empty` builtin backtracks to the preceding + generator expression. + + All jq functions can be generators just by using builtin + generators. It is also possible to define new generators + using only recursion and the comma operator. If the + recursive call(s) is(are) "in tail position" then the + generator will be efficient. In the example below the + recursive call by `_range` to itself is in tail position. + The example shows off three advanced topics: tail recursion, + generator construction, and sub-functions. + + examples: + - program: 'def range(init; upto; by): + def _range: + if (by > 0 and . < upto) or (by < 0 and . > upto) + then ., ((.+by)|_range) + else . end; + if by == 0 then init else init|_range end | + select(. < upto); + range(0; 10; 3)' + input: 'null' + output: ['0,3,6,9'] - title: Assignment body: |