jaq icon indicating copy to clipboard operation
jaq copied to clipboard

Some float and negative number differences to jq

Open wader opened this issue 1 year ago • 4 comments

I don't know if jaq aim to be jq compatible in these cases:

# jaq errors, jq ceils
jq -n '"abcd"[1.9:2.9]'
"bc"

# jaq errors, jq ceils codepoint
# jq -n '[106.9, 113.0] | implode'
"jq"

# jq master not 1.7.1
$ jq -n 'limit(-2; 1,2,3,4,5)'
jq: error (at <unknown>): limit doesn't support negative count
$ jaq -n 'limit(-2; 1,2,3,4,5)'
<empty>

# jaq errors
$ jq -n 'limit(2.1; 1,2,3,4,5)'
1
2
3

$ jq -n 'halt_error(2.1)'; echo $?
2
$ jaq -n 'halt_error(2.1)'
Error: cannot use 2.1 as integer

wader avatar Nov 11 '24 19:11 wader

My general reasoning is: In places where the decimal places of a float are ignored, providing a float should yield an error. From this follows that floats yield an error when they are used for indexing, implode, and halt_error.

limit is an interesting case: First, the same argument as for indexing applies to exclude floats in the first argument. My reasoning to allow negative numbers in the first argument is: limit($n; f) should return at most $n$ elements, meaning that negative $n are equivalent to 0. But I have to admit that I'm less sure about admitting negative values of $n$ than about forbidding floats. What do you think?

01mf02 avatar Nov 12 '24 08:11 01mf02

My general reasoning is: In places where the decimal places of a float are ignored, providing a float should yield an error. From this follows that floats yield an error when they are used for indexing, implode, and halt_error.

For jq i think it's a bit accidental how it behaves in some places :( some more consistency would have been nice. What about cases like this 10/2, 1.1 | trunc where the result could be an integer? still good with explicit conversion? i'm a bit torn how strict or terse jq should be and not throw errors when there could be not too confusing and useful non-erroneous behavior. Sorry for the non-answer, will have to think more about this :)

limit is an interesting case: First, the same argument as for indexing applies to exclude floats in the first argument. My reasoning to allow negative numbers in the first argument is: limit($n; f) should return at most $n$ elements, meaning that negative $n are equivalent to 0. But I have to admit that I'm less sure about admitting negative values of $n$ than about forbidding floats. What do you think?

Think im leaning towards your reasoning, negative will just be empty. It was changed in https://github.com/jqlang/jq/pull/3181, before negative for some reason (bug?) would emit all values, 0 was empty, and it was changed to be in align with nth.

wader avatar Nov 12 '24 09:11 wader

What about cases like this 10/2, 1.1 | trunc where the result could be an integer?

The case for 10/2 is different from the rest of the cases in this discussion, because there, both arguments are integer. Anyway, this falls under the two rules given in the README:

  • The sum, difference, product, and remainder of two integers is integer.
  • Any other operation between two numbers yields a float.

trunc is a bit of a special case because it inherits its semantics from libm. So even if by my rules, it should yield an integer, it does not, because otherwise, it would not respect the libm semantics.

01mf02 avatar Nov 12 '24 16:11 01mf02

By the way, talking about trunc: I see that you use trunc quite a bit in jqjq, but I believe that using floor (or round?) might be more appropriate. This is because trunc returns a float, while floor/round return integers.

01mf02 avatar Nov 13 '24 10:11 01mf02