Is the jq + operator eager? - jq

I originally wrote my jq command as
.data.viewer.zones[] | .httpRequests1mGroups[0].sum|with_entries(select(.key|endswith("Map")|not)) + {"zoneTag": .zoneTag}
and got this result:
{
"bytes": 2875120330,
"cachedBytes": 1475518778,
"zoneTag": null
}
{
"bytes": 2875120330,
"cachedBytes": 1475518778,
"zoneTag": null
}
zoneTag is the last attribute in a zones object.
I rewrote the command as
.data.viewer.zones[] | {"zoneTag": .zoneTag} + .httpRequests1mGroups[0].sum|with_entries(select(.key|endswith("Map")|not))
and get what I expected:
{
"zoneTag": "zone 1",
"bytes": 2875120330,
"cachedBytes": 1475518778,
}
{
"zoneTag": "zone 2",
"bytes": 2875120330,
"cachedBytes": 1475518778,
}
My question is why? Is + eager? (I get the same results using *.)
Thanks.

So maybe you're looking for an explanation in terms of operator precedence.
Let:
A represent .data.viewer.zones[]
B represent .httpRequests1mGroups[0].sum
C represent with_entries(select(.key|endswith("Map")|not))
Then your first jq expression is equivalent to
A | B | C + {zoneTag}
whereas your second is equivalent to:
A | {zoneTag} + B | C
So in the first case, {zoneTag} gets its value from B but in the
second case, it comes from A.

In jq, for most purposes, including that of object addition, an explicit null value in the object on the right is not the same as the absence of a key.
Thus if A is {"a": 1} then A + {} is A but A + {"a": null} is {"a": null}.
Thus the "right-most value" rule must be understood to mean "right-most explicit value".
Whether any of this has to do with "eagerness" depends on your understanding of that term.
Non-lazy evaluation
In jq, object addition (and indeed addition in general) proceeds from right to left and is of course non-lazy, as can be seen in the following example, which also illustrates the RHS-dominance mentioned above.
jq -n '{a:(1|debug)} + {b: (2|debug)} + {a:(3|debug)}'
["DEBUG:",3]
["DEBUG:",2]
["DEBUG:",1]
{
"a": 3,
"b": 2
}
So far as I know, though, the right-associativity might not be guaranteed.

Related

How to continue a while loop while the condition is false in r?

I have this while loop:
while (abs(B-left)<INFSMALL | abs(B-right)<INFSMALL) {
...
}
I want it to run while the above condition is FALSE. Is there an easy way to do this?
Use one of:
Negate the entire conditional by wrapping it with !(.), as in
while (!(abs(B-left) < INFSMALL || abs(B-right) < INFSMALL)) {
...
}
Negate the components inside, and change from OR to AND:
while (abs(B-left) >= INFSMALL && abs(B-right) >= INFSMALL) {
...
}
You should be using || instead of |, see Boolean operators && and ||. The flow-control functions if and while need the conditional to be length-1 exactly, not 0, no more than 1. While | will produce a vector of length 1 if all of the arguments are length 1, there are two reasons this is still a bad idea:
Short-circuiting: in general, if the first (of multiple, chained) conditional suggests that the second (and beyond) conditional does not matter, than short-circuiting means it will not evaluate them. Without predefining aa, for instance, compare
exists("aa") && aa > 0
# [1] FALSE
exists("aa") & aa > 0
# Error: object 'aa' not found
Declarative code: the control-flow while must only take length-1, make sure you know this going in. It's perhaps a little bit of style, so more-so #1 above.

Regarding OCaml Pattern Matching Syntax

I am following this OCaml tutorial.
They provided the two functions below and said that they are equivalent.
let string_of_int x = match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
let string_of_int2 = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
My query is regarding the syntax of the above functions.
I wrote the same function but instead of | 0 -> I simply did 0 -> and the function still works in the same way. Is there any particular reason that the tutorial added the extra | in their function?
In the second function what is the use of the function keyword and why was this keyword absent in the first function?
Some people think it looks nicer and more organized, and it allows you to change the order of cases using cut & paste without having to worry about which one didn't have the |.
The function syntax is an abbreviation: function [CASES] is the same as fun x -> match x with [CASES]. There is a subtle difference, which is with function it is not possible to shadow another variable by the name of the parameter.
let string_of_int x = [EXP] is itself an abbreviation for let string_of_int = fun x -> [EXP].
So, to a close approximation, the "canonical" syntax uses fun and match, everything else is sugar. If you apply these two expansions to the two versions of the function, you will see that the same code results (modulo alpha-equivalence, of course :) ).

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

Rewrite recursive BNF rule with iteration

Look at the following recursive BNF rule
(1) X = Xa | b
This produces sentences like
X = b
X = ba
X = baa
X = baaa
...
This can be written as
(2) X = b a*
where the right hand side is not recursive
Now take a look at the following recursive BNF rule
(3) X = { X } | b
This produces sentences like
X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
Is there some way to rewrite rule (3) in a non recursive way, analogous as we did when we rewrote rule (1) to rule (2).
Observe that X = {* b }* is no good since the parenthesis need to be balanced.
I do not know if the question above is possible to answer. The reason for the question above was that I wanted to avoid infinite loop in my parser (written in Java). One way was to insure that the BNF rules are not recursive, hence my question. But another way is to use the recursive rule, but avoid the infinite loop inside my (Java) program. Turns out that you can avoid loops by lazy instantiation.
For instance look at the following rules:
expression = term ('+' term)*;
term = factor ('*' factor)*;
factor = '(' expression ')' | Num;
expression() calls term(), which calls factor(), which calls expression(), thus we can end up with infinite loop. To avoid that we can use lazy instantiation, so instead of writing something like:
public Parser expression() {
expression = new ...
return expression;
}
we instead write:
public Parser expression() {
if (expression == null) {
expression = new ...
}
return expression;
}
Observe that you must declare expression as an instance variable to get this to work.

Binary trees as innested pairs

I'm trying to represent a generic binary tree as a pair.
I'll use the SML syntax as example. This is my btree type definition:
datatype btree = leaf | branch of btree*btree;
So, I'd like to write a function that, given a btree, print the following:
bprint leaf = 0
bprint (branch (leaf,leaf)) = (0,0)
bprint (branch (leaf, branch (leaf,leaf))) = (0, (0, 0))
and so on.
The problem is that this function always return different types. This is obviously a problem for SML and maybe for other functional languages.
Any idea?
Since all you want to do is to print the tree structure to the screen, you can just do that and have your function's return type be unit. That is instead of trying to return the tuple (0, (0, 0)) just print the string (0, (0, 0)) to the screen. This way you won't run into any difficulties with types.
If you really do not need a string representation anywhere else, as already mentioned by others, just printing the tree might be the easiest way:
open TextIO
datatype btree = leaf | branch of btree * btree
fun print_btree leaf = print "0"
| print_btree (branch (s, t)) =
(print "("; print_btree s; print ", "; print_btree t; print ")")
In case you also want to be able to obtain a string representing a btree, the naive solution would be:
fun btree_to_string leaf = "0"
| btree_to_string (branch (s, t)) =
"(" ^ btree_to_string s ^ ", " ^ btree_to_string t ^ ")"
However, I do not really recommend this variant since for big btrees there is a problem due to the many string concatenations.
Something nice to think about is the following variant, which avoids the concatenation problem by a trick (that is for example also used in Haskell's Show class), i.e., instead of working on strings, work on functions from char lists to char lists. Then concatenation can be replaced by function composition
fun btree_to_string' t =
let
fun add s t = s # t
fun add_btree leaf = add [#"0"]
| add_btree (branch (s, t)) =
add [#"("] o add_btree s o add [#",", #" "] o add_btree t o add [#")"]
in implode (add_btree t []) end

Resources