3 ms·
I tend end to struggle with this sort of lispy syntax as I use a regular shell (rather than one in emacs) which makes balancing parens hard, and the syntax is o
by dan-robertson 7y ago
I tend end to struggle with this sort of lispy syntax as I use a regular shell (rather than one in emacs) which makes balancing parens hard, and the syntax is otherwise verbose. If I’m using a query tool like this it will be interactively writing a one-liner so I want syntax that’s easy to get right (balancing parens by hand is hard), easy in the usual case (eg I think it should accept some way to use symbols to name fields in a record because typing and balancing double quotes all of the time is a waste of time) and easy to append to (I will run a query, press up, move to the end of the query, and modify. In this case I think moving to the end involves counting parens).
Perhaps I would want some implicit pipe or threading at the top level (which could be turned off with some option for scripts I guess).
Another helpful feature could be adding the magic closing paren: ] which will close all open parens to the top level. E.g. these two lines are equivalent:
(foo (bar (baz) whizz))
(foo (bar (baz) whizz]
A completely different (and less powerful) paradigm I like is one of match-format where the pattern looks a lot like what it’s trying to match. In this case most functions and fancy transformations are impossible. So you could write something like this to extract the list of countries:
j '{countries: %%}'
Or to extract each country’s name:
j '{countries: [ .*, { name: %% }, .*]}'
(Presumably you would have syntax for trying to match against each array element). (I also would make commas optional but I’m trying to make this syntax obvious).
Or to list the keys of the 0th element:
j '{countries: [ { %%: . }, .* ]}'
Or to get name and population:
j '{countries: [ .*, { name: %name, population: %pop }]}'
The output might look like:
{ "name": "Poland", "population": "38000000" }
————————
An alternative query tool which I haven’t really seen before would be one which is interactive rather than repeatedly run: you pipe your json (or whatever) into it and it spins up some kind of (curses) gui shoeing you your data with a nice interface to interactively write your query and see its results. It could finish by outputting a command line to run the query non-interactively.
The closest thing to this I know of is a small programming by example demo that came out of Microsoft research. The goal was to figure out how to extract some desired data from some big blob of json (or maybe html, I don’t remember). The user would see the json in some web gui and could click on the data they wanted and the app would try to figure out the “most obvious” query to get it. If they clicked on the country name, I think it would probably suggest a query for all the countries’ names (but maybe that would be the second option). I think it would also try to be clever about grouping, so if the user picked name and population it would hopefully figure out that they should come in pairs rather than being two independent lists that might not be the same length.
- cube2222 7y agoThanks so much for so much feedback! There's already an issue to automatically add trailing parens and I definitely think it's a good idea, as balancing parens really is annoying in-shell. I didn't think of it before. I decided that adding interactivity would be too much work, but you could definitely put together a oneliner (or alias) which achieves that using fzf: https://paweldu.dev/posts/fzf-live-repl/ https://paweldu.dev/posts/fzf-live-repl/ Overall I encourage you to try write a tool that has the syntax you described, as it sounds plausible! It kinda looks a little bit like graphql, so maybe that would fit?
- dan-robertson 7y agoI wonder if it’s worth writing some read line macros (and instructions for setting them up) for eg inserting ( ) <move-cursor-backwards>. (Bound to M-( in emacs) I think they help for simple sexp editing. I also wish I had something like “run this command but when it’s done show me a prompt with the same command and my cursor in the same place” but I have no idea if it’s easy
- cube2222 7y agoI didn't know about readline macros, thanks for mentioning them. I'll think about it.
- cube2222 7y agoI've written the interactivity oneliner: echo '' | fzf --print-query --preview-window wrap --preview 'cat test.json | jql {q}'