Document TCO a bit more

This commit is contained in:
Nicolas Williams committed 2014-08-05 01:15:33 -05:00
1 parent 2518b3a34f
commit 2159f9f5e0
1 file changed
+23 -9
+23 -9
View File
@@ -1245,9 +1245,10 @@ sections:
The `while(cond; update)` function allows you to repeatedly The `while(cond; update)` function allows you to repeatedly
apply an update to `.` until `cond` is false. apply an update to `.` until `cond` is false.
Note that `while(cond; update)` is internally defined as a jq Note that `while(cond; update)` is internally defined as a
function written in jq, using only functional constructs. See recursive jq function. Recursive calls within `while` will
advanced topics below. not consume additional memory if `update` produces at most one
output for each input. See advanced topics below.
examples: examples:
- program: '[while(.<100; .*2)]' - program: '[while(.<100; .*2)]'
@@ -1293,10 +1294,9 @@ sections:
calling `recurse` without arguments. This alias is considered calling `recurse` without arguments. This alias is considered
*deprecated* and will be removed in the next major release. *deprecated* and will be removed in the next major release.
These `recurse` filters are all written to take advantage of The recursive calls in `recurse` will not consume additional
jq's optimizations of certain cases of tail recursion. In memory whenever `f` produces at most a single output for each
particular, there is no memory overhead due to the input.
recursion.
examples: examples:
- program: 'recurse(.foo[])' - program: 'recurse(.foo[])'
@@ -1717,7 +1717,7 @@ sections:
of each capture as the key, and the matched string as the of each capture as the key, and the matched string as the
corresponding value. corresponding value.
example: examples:
- program: 'capture("(?<a>[a-z]+)-(?<n>[0-9]+)")' - program: 'capture("(?<a>[a-z]+)-(?<n>[0-9]+)")'
input: '"xyzzy-14"' input: '"xyzzy-14"'
output: '{ "a": "xyzzy", "n": "14" }'' output: '{ "a": "xyzzy", "n": "14" }''
@@ -1967,7 +1967,21 @@ sections:
body: | body: |
As described above, `recurse` uses recursion, and any jq As described above, `recurse` uses recursion, and any jq
function can be recursive. Tail calls are optmized. function can be recursive. The `while` builtin is also
implemented in terms of recursion.
Tail calls are optmized whenever the expression to the left of
the recursive call outputs its last value. In practice this
means that the expression to the left of the recursive call
should not produce more than one output for each input.
For example:
def recurse(f): def r: ., (f | select(. != null) | r); r;
def while(cond; update):
def w: if cond then ., (update | _while) else empty end;
try _while catch if . == "break" then empty else . end;
- title: Generators and iterators - title: Generators and iterators
body: | body: |