-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 head and tail builtins #2882
base: master
Are you sure you want to change the base?
Conversation
These primitives helped me in implementing some convenience functions on top of them: https://github.com/reegnz/dotfiles/tree/master/jq Most notably converting to/from camelcase. Capitalizing strings is also easier to implement with such primitive filters exposed by jq. |
head: * returns a single value or empty if input is a list * returns a string or empty if input is a string * fails if input is neither list or string tail: * returns a list if input is a list * returns a string if input is a string * fails if input is neither list or string
f4971ae
to
7968229
Compare
Alternatively, one could use these as heads and tails (more cryptic, but gets the job done: For lists: [ .[:1][], .[1:]] For strings: [.[:1], .[1:]] The unwrapped head for lists is inspired by other languages usually called destructuring, eg.: |
[ "a", "bc" ] | ||
|
||
[head, tail] | ||
[ "a" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is failing
Expected ["a",""], but got ["a",[]]
@@ -169,6 +169,8 @@ def nth($n; g): | |||
else label $out | foreach g as $item ($n + 1; . - 1; if . <= 0 then $item, break $out else empty end) end; | |||
def first: .[0]; | |||
def last: .[-1]; | |||
def head: select(length >0) | .[:1] | if type == "array" then .[] end; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the tests, it seems more accurate to think of these functions as
firstItem
and remainingItems
.
Calling them head
and tail
seems misleading because it implies they would work like the equivalent shell commands that read the start and end of a file for n lines.
Instead, head
always returns one item, while tail
returns all except the first item.
I'm not confident these functions (in their current state) would be useful as builtins for the community as a whole. They seem like more of a niche thing that could exist in an independent module as seems to be the current case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @reegnz references in #2882 (comment) the head and tail terminology comes from pattern matching in function languages.
[ 1 ] | ||
[ 1, [] ] | ||
|
||
[head, tail] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given it's possible for head
to return empty
values, it's probably better to write tests that check these functions independently. Otherwise, in tests like this, it's not obvious which function returned an empty
value.
Sorry to be so negative, but I don't see the point of these additions, and indeed based on my present understanding, they seem to just add bloat at best and confusion at worst (confusion, because of the history of Perhaps I'm missing something? Please feel free to enlighten me :-) |
I don't mind the specific terminology used. Can be Calling it bloat sounds funny to me. It's true, most functional languages are complex because they have stdlib-s with higher order abstractions shipping with them. Wouldn't call that bloat though, that's a pretty big stretch. Just please give this the benefit of the doubt instead of straight up calling it bloat and dismissing it. People do make use of taking the first item and remaining items of a list. An alternative to filters is to make destructuring a language-level feature, like in javascript and clojure. |
BTW original issue I've opened was #2260 this was just a quick run at the problem, I don't mind how it's solved. |
head:
tail: