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
A simple way to concat-and-assign (like foo+=bar
)
#1326
Comments
Linked to #156 I guess. |
Concatenation already exists. Pattern matching as well, but it requires
|
That is not "concat_and_assign" though, so that gives unwieldy results for non-trivial variables and strings. I'd love to have a Compare and contrast this and this, or this and this. The non repetition of the variable name makes it both more readable and easier to maintain (DRY and PEP8 "readability counts"). I think we can agree on abusing |
If you want an function append --no-scope-shadowing
if test (count $argv) -ne 2
echo append: Expected two arguments, (count $argv) received.
return 1
end
set -l __fish_value $$argv[1]
set $argv[1] "$__fish_value$argv[2]"
end And example, just to show it really works.
I rarely saw a situation where As for pattern matching, I think something like this can work. function match
if test (count $argv) -ne 2
echo match: Expected two arguments, (count $argv) received.
return 1
end
switch $argv[2]
case $argv[1]
return 0
end
return 1
end Example, as always:
|
Thanks. Both of those are great. Awk and perl are not useful when you're implementing a rich fish config and prompt, and for performance to be great you have to stay as much as possible in the shell, which pushes its scripting language to the limit. In unscientific tests with the above linked features, all advantages of fish in performance are lost to zsh and even bash solely due to the need to repeatedly call sed. Allow me to veer a little out of topic. If fish had more 'fringe' features (in terms of the law of minimalism) like this, thus widely increasing the immediate usefulness of the language while only adding a very limited maintenance burden, I would readily use it much more to write scripts than perl or awk. Currently having a choice between bash (useful, piles of historical hacks) and perl/python/awk (more expressive, cleaner) makes me feel there's a need for something in between, and fish has all it takes to fill that void but those 'fringe' features that makes it feel like a minimalist but robust script language. |
👍 for the string matching |
Everything here that's not concat-and-assign is in #156, so I'm renaming this. |
foo+=bar
)
Just to make it explicit, I'm requesting $ set food chicken
$ set -a food soup
$ for f in $food
echo food: $f
end
food: chicken
food: soup |
We're obviously never going to implement I'm a big fan of the Zen of Python maxim that
|
I intend to close this as will-not-implement in the near future unless someone can provide a better argument than is already present in this issue as to why we need |
Also, see issue #436 which proposes adding options for appending and prepending to variables. |
I generally agree with that, however a perhaps more important and universal maxim is DRY (don't repeat yourself), and it seems like the You have a good point about a prepend option. It would seem inconsistent to have one and not the other. I feel like append is a more commonly needed operation, and it would seem prudent to not use up single-letter switches too early, so I would be content with having just the append operation for now, and waiting to see if anyone actually requests prepend. |
I am still unconvinced that The need for an explicit append syntax in bash is primarily due to its adherence to POSIX 1003.1. That affects how variables are interpolated, and split again, on Appending and prepending to lists is a common feature of other languages (e.g., C++ and Python). Providing syntactical sugar for doing so in fish might be useful. But I'm not convinced it is useful enough to implement. Nonetheless, despite my previous comment I'm not going to close this "will-not-implement" because I think it deserves more discussion. |
+1 for |
One thing I've noticed here is that the metasyntactic variables ("foo" and "bar") might be obscuring the issue a bit since they are short. So I submit to you what might be the longest variable name in fish: "___fish_git_prompt_color_flags". Note that it is 30 characters long, so with a common line length limit of 80, you'd have 15 characters to work with on one line (30 * 2 + "set" + 2 spaces between), less with indentation. set ___fish_git_prompt_color_flags a $___fish_git_prompt_color_flags something Now, can you see what I've added to the variable, at a glance? Did you see that I prepended the "a"? Also notice that that is 78 characters, so with our 4-space indentation it could only appear in the global block without going over 80 characters. With set --append ___fish_git_prompt_color_flags something
set --prepend ___fish_git_prompt_color_flags a Is that more readable, or less? Granted, this is the worst case and we don't try to make code as short as possible (otherwise we'd have fifty glob qualifiers and curly braces instead of "begin/end"), but we do try to go for readability and in this case I'm having a needle-in-a-haystack experience. |
Yes, I can. Precisely because we don't have flags to append or prepend. I simply looked past the var name being set and saw the first value was The main problem I have with this proposal is it doesn't materially make the operation simpler or clearer. Nor do I find arguments about commonly used terminal widths compelling. Especially since the script that defines the var you used in your example, @faho, already has quite a few extremely long lines. Too, few vars have names that long and those that do should arguably be shortened. And in most cases replacing an explicit Lastly, the issue has been open three years and the implementation is trivial. If someone felt even moderately strongly about this it would be implemented by now. The one argument that might convince me to implement this would be that it is a significantly faster, more efficient, means of prepending/appending values to vars. I have no doubt that would be true for pathological cases such as a var with a thousand values averaging a thousand chars each. The question is whether it is likely to be measurable, let alone noticeable, with typical fish scripts. We're probably getting close to the point where the time spent discussing this proposed enhancement is equal to the time required to implement it. What I love about the Python language is the The Zen of Python. Which states "There should be one-- and preferably only one --obvious way to do it." We already have an obvious way to safely prepend and append to variables. I am unconvinced we need another way to do so. |
Also this example
is confusing. Is |
I would like to challenge the use of the word 'obvious' here. I don't find it obvious at all. Do you remember if it was obvious to you the first time? Is it possible you have just done it enough that now it is comfortable to you? |
Yes, @ElijahLynn, it was obvious to me the first time I needed to append/prepend an element to a var. Because it is consistent with these examples:
Those and the
Except that, assuming I was simply ambivalent about implementing this feature. But given what I just wrote I am now opposed to implementing it. |
That's actually a really good point.
I'm convinced as well. |
I respectfully disagree.
|
So you're arguing that we implement a feature that is certain to confuse a non-negligible percentage of users, especially those who recently switched from bash, and doesn't actually implement a new capability just to avoid having to repeat a long variable name? And speaking of confusing behavior here's bash:
The longer I spend using fish the more perplexed I am why people are so enamored of the steaming mess that is bash/zsh and argue that fish should be more like those shells. |
I disagree that it would be certain to confuse many people, but who's to say. :)
Fish is very different from Bash, and there is no similar functionality in Bash (i.e. nothing like
Personally, I appreciate the DRY principle, and I think the example faho gave earlier is a good one (despite his changing his mind since then). One of the purposes of Fish is to provide a syntax with greater clarity, and while the For those reasons, I think it would be a worthy addition to Fish.
Yes, I agree, Bash's array syntax is absolutely awful. One of the things I like about Fish is that working with arrays is much easier. However, I think that appending to arrays is actually more pleasant in Bash than in Fish. I think adding My two cents. Cheers. |
There is:
This issue is arguing for adding the equivalent of that second statement only in a fishy way. The problem as I pointed out with my previous example is that the fact such syntax is required confuses people. If you don't include those parens you end up concatenating to the first element of the array. Adding a |
@alphapapa, can you provide some justification for your statement:
My experience is that appending to vars which or may not be arrays in bash/zsh is less pleasant than fish. |
What I mean is, I prefer this: var+=(element) over this: set var $var element ...because the So a syntax like: set -a var element unambiguously appends to an array, and avoids repetition of the variable name, making for consistent syntax. |
I've decided this is actually worthwhile. Primarily because variable expansion is itself moderately expensive. So from the perspective of making fish script fast it would be better to write |
Upon further reflection I am less worried about people being confused regarding the order of the arguments. The proposed syntax is consistent with the existing assignment syntax where the var name without a leading dollar-sign appears first. So I think my earlier concerns, while valid, were overly pessimistic. |
Merged to |
Thanks for implementing this, Kurtis! Looking forward to using it in my scripts! |
Manipulating string ins fish basically requires
A list of things that bash/zsh support that makes everyone life's easier and faster:
foo+="bar"
[ $haystack = *needle* ]
(notcontains
)Those largely make calls to sed/grep/awk/basename/dirname useless, thus improving performance a lot in many cases, e.g #1325.
The text was updated successfully, but these errors were encountered: