MiSawa / xq

Pure rust implementation of jq
MIT License
318 stars 18 forks source link

xq vs jaq #170

Closed jayvdb closed 10 months ago

jayvdb commented 10 months ago

Hi, I am curious why xq is being developed when https://github.com/01mf02/jaq existed and was quite functional before xq was started. Was it not known? Now it is known, what is the goal difference?

I have a few simple jq queries which work with both xq and jaq, and I am wondering which I should put into my CI scripts. xq is smaller, yet sufficient, but the README tells me not to use xq. ;-(

itchyny commented 10 months ago

I'm not the author of xq and not sure about the original motivation, but let me comment here as the author of gojq. The design of xq and jaq are quire different. While jaq redesign the execution model and fixes various behaviors for its correctness and performance goal, xq is just a Rust implementation of jq and its execution model is very similar to the original (gojq is similar too). Based on the goal about correctness, jaq's behavior is quite different from the original even in simple query like jaq -n '.foo'. And even a basic and important filter like path/1 is missing in jaq. The assignment and update-assignment operators of jq are implemented based on this path/1 filter, but jaq updates the value without construction paths for higher performance. This difference sometimes causes jaq to panic; jaq -n '[[]] | .. = ..' overflows its stack. On the other hand, xq implements very similar execution model than jq, and xq passes more jq compatibility tests than jaq. The xq command implements path functions (path/1, getpath/1, setpath/2), so it is capable to include the pick/1 filter easily (introduced in jq 1.7); xq -n 'def pick(f): . as $v | reduce path(f) as $p (null; setpath($p; $v | getpath($p))); {x:1,y:2,z:3} | pick(.y)' works as expected (Needs much more Rust coding to implement this in jaq). However, I'm not blaming, this is just design difference. I'd like to express my respect to the jaq author, the paper Denotational Semantics and a Fast Interpreter for jq describes very well about the semantics about jq, and we can learn a lot from it. While jaq was created from academic motivation of studying denotational semantics and performance improvement, xq was created from simpler motivation to Learn jq.

MiSawa commented 10 months ago

Was it not known? Now it is known, what is the goal difference?

I was not aware of jaq until I found it later, but that wouldn't have affected the decision of making xq, because the motivation was to learn/understand jq as itchyny mentioned.

I have a few simple jq queries which work with both xq and jaq, and I am wondering which I should put into my CI scripts. xq is smaller, yet sufficient, but the README tells me not to use xq. ;-(

I'd personally recommend jq or gojq over xq as they're well-used and maintained better. If Rust tools is really preferred, I'd personally use xq because I know xq, and it can be replaced to jq/gojq later easily if something went wrong. Though I'm very biased. jaq is used/maintained more than xq, and it's perfectly reasonable to choose jaq.