Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mul/0 builtin filter folding arrays with * similar to add/0 for + #3048

Open
syco opened this issue Feb 22, 2024 · 3 comments
Open

Add mul/0 builtin filter folding arrays with * similar to add/0 for + #3048

syco opened this issue Feb 22, 2024 · 3 comments

Comments

@syco
Copy link

syco commented Feb 22, 2024

jq/ChangeLog

Lines 826 to 829 in 913b264

Add a recursive object merge strategy and bind it to *
This commit adds a jv_object_merge_recursive function, that performs
recursive object merging, and binds it to multiply when applied to
two objects.

Hi,
when you add multiple files you can do either jq -s '.[0] + .[1] + .[2]' file0.json file1.json file2.json or jq -s 'add' *.json

can we have a similar syntax for jq -s '.[0] * .[1] * .[2]' file0.json file1.json file2.json ?
Could maybe be: jq -s 'multiply' *.json

Thanks

@itchyny
Copy link
Contributor

itchyny commented Feb 23, 2024

There is a pull request for this feature #1643. My concern is what [] | mul should be. Considering null is the identity element of addition (i.e. null + x == x + null == x for any value x regardless of type), [] | add == null is reasonable. However, there is no identity element of multiplication (while {} is the value for objects, 1 is the value for numbers). #1643 suggests using null for the value, but mathematically speaking, it's very weird that the additive identity and the multiplicative identity are the same value.

@syco
Copy link
Author

syco commented Feb 23, 2024

I don't know if I would have considered null as the additive identity. Typed languages throw an error trying to add null and numbers. The only language where null is the additive identity afaik is javascript.

But regardless of that I would have mul to follow the same identical logic as *,
so echo '[{"a": 1}, {"b": 2}]' | jq '.[0] * .[1]' can be written as echo '[{"a": 1}, {"b": 2}]' | jq 'mul'
and echo '[null, {"b": 2}]' | jq 'mul' throws an error same as echo '[null, {"b": 2}]' | jq '.[0] * .[1]'

(I would make null + x throw an error as well, but that's not the point here)

@itchyny
Copy link
Contributor

itchyny commented Feb 23, 2024

The point is add is the folding operation of addition. Since null is the additive identity, add is cleanly defined as def add: reduce .[] as $x (null; . + $x);. Since we don't have multiplication identity now, we will end up making [] | mul to throw an error (something like def mul: if length == 0 then error("cannot use mul/0 on empty array") else reduce .[1:][] as $x (.[0]; . * $x) end).

@itchyny itchyny changed the title Add top level function for this change Add mul/0 builtin filter folding arrays with * similar to add/0 for + Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants