3 ms·
The one thing I dislike about jq is that it treats many-things and one-thing the same way. This PL design choice is IMO fraught with peril. Its the reason why j
by spion 4y ago
The one thing I dislike about jq is that it treats many-things and one-thing the same way. This PL design choice is IMO fraught with peril. Its the reason why jq can't have a "slurp" filter. Treating many-things the same way means there is no first-class representation of a json stream, which in turn means there are no functions that can operate on a JSON stream as a whole.
If JQ had first-class streams, most code would've looked quite pedestrian. Everything that operates on many values would need some kind of `map`, there would also be `reduce` as a normal filter, as well as slurp - and the overal weirdness of programs would significantly decrease - the code would look exactly like normal functional programming pipelines.
- odnoletkov 4y agoIt's 'zero-class' representation – everything is a json stream. You can slurp any stream into an array by wrapping it with the `[]` operator: $ jq -n '[range(3)]' [ 0, 1, 2 ] Do you mean that you can't 'slurp' a stream from inside the pipeline? It makes sense since parts of the pipeline just process individual values, they are not supposed to have context of the whole stream. So to slurp you need to 'wrap around'. I agree this is unconventional, but it what enables many of the advantages like pipeline structure of the program and conciseness (rare need for parameters/variables/functions)
- spion 4y ago> It makes sense since parts of the pipeline just process individual values, they are not supposed to have context of the whole stream. > I agree this is unconventional, but it what enables many of the advantages like pipeline structure of the program and conciseness I'm not sure I agree with this. There are no operators that work on streams other than `select` since most other operators are ambiguous. This means streams are not first-class values (they are not at the same level as all other values). It doesn't have to be designed this way, if we differentiate between stream and nonstream values you could have '.someattr[] | smap(.otherattr) | sreduce(+)' where `smap` is a stream equivalents to `map` The language won't be as compact but it will gain significantly in readability and consistency, and its pipelining will continue to work just as well. Its like designing a language where everything is an array and where every operation implicitly maps over the array. In those cases you can't have a "reduce" operation, because its ambiguous whether you want to run reduce on every individual element or you want to reduce the entire array of elements.