[HN Gopher] Fish - Update on the Rust port
___________________________________________________________________
Fish - Update on the Rust port
Author : rhim
Score : 220 points
Date : 2023-11-26 18:48 UTC (4 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| behnamoh wrote:
| one of the fastest shells out there will probably get even
| faster. ever since I switched from zsh to fish, my terminal
| productivity has gone up a lot.
| bayindirh wrote:
| I don't think C++ and Rust has that big of a performance
| difference. They are probably neck to neck with no clear
| winner.
| LoganDark wrote:
| The real difference is in compile-time abstractions. It's
| much easier to organize things in Rust, especially with a
| borrow checker. You can confidently remove overhead while
| being sure that it'll continue to be memory safe.
| bayindirh wrote:
| With some strong design decisions, and with modern C++
| facilities, you can make sure that your code never does
| funny things in C++, too.
|
| Yes, Rust's BC is a great technology, but C++ is not a
| runaway nuclear fire which contaminates and melts
| everything around it when it comes to sanity and security.
|
| Yes, Rust allows you to run amok by not allowing it, but
| you can design a good foundation to your code which
| prevents tons of problems out of the gate in C++, and this
| is without using smart-pointers and other things available
| to you.
| pdpi wrote:
| > but you can design a good foundation to your code which
| prevents tons of problems out of the gate in C++,
|
| And there is an almost perfect overlap between the people
| capable of pulling off a rewrite like this and the people
| who would write a good C++ foundation in the first place.
| LoganDark wrote:
| > Yes, Rust's BC is a great technology, but C++ is not a
| runaway nuclear fire which contaminates and melts
| everything around it when it comes to sanity and
| security.
|
| I never meant to imply such a thing. However, Rust is
| simply a much better-defined language. Moves do what you
| expect, smart pointers work like you'd expect, there are
| not 3 (or 5) different types of constructors you have to
| understand and implement properly if you want to build
| your own abstractions. You don't have to remember where
| to put std::move, you don't have to remember what happens
| to the variable after you move out of it, you don't have
| to use the awful variant accessor functions if you want a
| tagged union and so on.
|
| Yes, you can do all this in C++. You can build safe
| abstractions. You can build layers on top of the STL to
| make it less awful. You can make use of modules and
| #embed and other nice new features that C++ is getting.
| _But you need to be a lot more careful compared to Rust,
| because the compiler is not going to help you._
| joshlk wrote:
| In Rust it's easier to leverage external crates/libraries
| that are more optimised than rolling your own. This can lead
| to performance increases (I don't know if fish is doing this)
| starcraft2wol wrote:
| C programs without libraries tend to be really fast for the
| opposite reason. So this isn't persuasive even though it
| seems like it should be true
| bayindirh wrote:
| I have never experienced difficulties adding high (HPC
| level) performance libraries into my code. Can you
| elaborate?
| dwattttt wrote:
| It definitely makes a difference around threading;
| exposing thread safety in function API makes it easy to
| understand where/how you can add threading support, or
| what is preventing it.
| nick__m wrote:
| I would not bet on this!
|
| from the link : We have no real idea what the
| performance of the finished port is going to be. Early results
| are encouraging, but it is entirely possible this will be ~20%
| slower in some cases.
| fbdab103 wrote:
| Is shell performance a limitation for some workflows? I naively
| think of it as some glue which shunts the work elsewhere. Maybe
| in the efficiency of pipe? I suppose those lunatics who write
| full programs in bash?
|
| I will always take faster code, but that seems like an odd
| bulletpoint to highlight given the many quality of life
| improvements fish has to offer.
| kstrauser wrote:
| Kind of, yeah. When I used zsh, oh-my-zsh made the shell
| startup _a lot_ slower, even though I wasn't going crazy with
| the customizations. Opening a new terminal tab would take a
| couple seconds to get a prompt. My current fish setup is
| imperceptibly fast to start.
|
| Those little delays add friction. Not an intolerable amount,
| sure, but it's there. While I switched to fish for other
| reasons, that alone would keep me from going back now.
| lkbm wrote:
| I once spent a while adding timings between each item in my
| zsh config files to find what was slowest.
|
| The nvm init was the worst of it, so now I have an alias
| for `$NVM_DIR/nvm.sh ] && \\. "$NVM_DIR/nvm.sh" && \\.
| $NVM_DIR/bash_completion` I just run manually before using
| nvm, rather than letting it slow me down half a second or
| whatever it was every time I open a new terminal.
|
| It's worth poking around if things get slow enough to be a
| pain. There's a decent chance it's 1-2 things that you
| don't even care about all that much.
| paradox460 wrote:
| You might check out rtx[1]
|
| Its an asdf[2] rewrite, in rust, that can do most of the
| things nvm can
|
| [1] https://github.com/jdx/rtx
|
| [2] https://github.com/asdf-vm/asdf
| dividedbyzero wrote:
| fish actually has a built-in profiler for its startup
| that can be enabled via an argument:
|
| > --profile-startup=PROFILE_FILE > Will write timing for
| fish startup to specified file.
| arp242 wrote:
| zsh has the same; just add "zmodload zsh/zprof" at the
| top and "zprof" at the bottom of your zshrc.
| coldtea wrote:
| > _Kind of, yeah. When I used zsh, oh-my-zsh made the shell
| startup a lot slower, even though I wasn't going crazy with
| the customizations_
|
| A lot or most of that wasn't zsh being slow though, but oh-
| my-zsh calling out to external programs (like git to get
| powerline info and such) and them being slow.
| arp242 wrote:
| See my other comment from earlier today[1] - launching
| 230 external programs (even very simple ones, /bin/[ in
| this case) takes about half a second. Since I would rate
| anything as >100ms to be a "noticeable delay" you have a
| "budget" of about 40 external processes, probably a bit
| less in real-world conditions (depending on which
| utilities you're using and what it's doing).
|
| And that's 40 _C_ processes. "python empty.py" takes
| about 30ms to 40ms due to the interpreter startup time;
| empty C file is about 2ms, "sh empty.sh" is about 4ms.
|
| Please think that "launching external programs is fast
| and modern computers are fast, so why worry about this?",
| and that's true, but it's also not. Add up a few dozen
| and turns out it's actually quite slow.
|
| [1]: https://news.ycombinator.com/item?id=38421199
| kstrauser wrote:
| True, but I can get the same functionality with fish
| without the slowdown. I don't think zsh is bad. I
| understand what was making it slow. I'm just glad I can
| have all of those niceties _plus_ fish's speed.
| jonS90 wrote:
| If it takes 5 seconds for your prompt to display or become
| interactive, yes.
|
| As far as I'm aware, most of the other quality of life
| improvements can be reproduced in zsh with plugins. This
| performance bulletpoint makes me want to consider switching
| back to fish from zsh.
| bch wrote:
| > one of the fastest shells out there will probably get even
| faster [...] my terminal productivity has gone up a lot.
|
| Surely you're not typing and managing jobs at a pace where C vs
| C++ vs Rust vs $lang matters... or I'm missing something about
| what fish is bringing to the table.
| cube2222 wrote:
| 1. It's amazing that they're doing this as a gradual C++ to Rust
| rewrite, while keeping it working end-to-end, if I understand
| correctly.
|
| 2. It's amazing how quickly this is going.
|
| 3. If you haven't tried fish yet, make sure to do so! It's a
| really ergonomic shell and overall very pleasant to use, with
| good defaults (you don't have to customize it, even though you
| can, for a great experience). I've switched from bash a couple
| years ago and haven't looked back since.
|
| Bonus: you won't have to google how to write a for loop in bash
| ever again (which I, writing them rarely, and them being
| unintuitive enough, had to do every single time)!
| shmerl wrote:
| Tip for some easy to remember Bash loop constructs:
|
| Incremental index: for ((i = 0; i < 10; i++));
| do echo $i; done
|
| For iterating over an array: foo[0]=a
| foo[1]=b for i in ${foo[@]}; do echo $i; done
| cube2222 wrote:
| Just to illustrate for others, in fish that would be
| for i in (seq 10); echo $i; end
|
| or usually written as for i in (seq 10)
| echo $i end
|
| and that is already based on iteration, so for iterating over
| files, you'll similarly use for f in (ls);
| echo $f; end
|
| and it works the same for arrays.
| shmerl wrote:
| seq would work in bash too, but it's not part of the
| language, it's an external tool. C like syntax is more
| expressive I'd say for simple numerical increments.
| user982 wrote:
| Your example in fish: for i in (seq 10);
| echo $i; end
|
| directly translated to bash: for i in $(seq
| 10); do echo $i; done
| bravetraveler wrote:
| No need for _seq_ :) for i in {1..10};
| do echo $i ; done
|
| If, for whatever reason, you want leading zeroes - BASH
| will respect that. Do _{01..10}_
| paradox460 wrote:
| You don't even need the (ls) for file iteration:
| for i in * echo $i end
|
| Fish also has globstar out of the box, so you can do
| for i in **/* echo $i end
| arp242 wrote:
| zsh makes this so much easier. This doesn't capture $i, but
| covers most use cases of "I want to run something more than
| once": repeat 10; echo "repeat me"
|
| If you do need $i you can use a similar construct as bash,
| but more convenient: for ((i = 0; i < 10;
| i++)); echo $i for i in {0..10}; echo $i # {n..m}
| loops also work in bash for ((i = 0; i < 10;
| i++)); { echo $i; echo $i } # Multiple commands
|
| Short loops are hugely helpful in interactive use because
| it's much less muckery for short one-liners (whether you
| should use them in scripts is probably a bit more
| controversial).
|
| Also looping over arrays "just works" as you would expect
| without requiring special incantations:
| arr=(a b) for v in $arr; echo $v
|
| ---
|
| Whether zsh or fish is better is a matter of taste, and
| arguably zsh has too many features, but IMHO bash is
| absolutely stuck as a "1989 ksh clone" (in more ways than
| one; it uses K&R C all over the place, still has asm hacks to
| make it run on 1980s versions of Xenix, and things like
| that).
| JNRowe wrote:
| Any reason to eschew short_loops in general that you're
| aware of? I ask because I'd probably use `for i ({0..9})
| echo $i` in your for loop example. I've never managed to
| get my head around the necessity for a narrow short_repeat
| option when there is - for example - no short_select.
|
| All of the zsh alternate forms _feel_ far superior to me,
| in both interactive use and within scripts.
|
| _JNRowe notes the many off-by-one translations in other
| examples and tips hat to arp242_
| arp242 wrote:
| Oh yeah, I forgot about the {n..m} syntax; I almost
| always use repeat these days or the C-style loop if I
| need $i, as that's more "in the fingers", so to speak,
| from other languages, even though {n..m} is easier.
|
| I don't know why you would want to avoid short loops,
| other than subjective stylistic reasons (which is
| completely valid of course). The patch that added
| short_repeat just asserts that "SHORT_LOOPS is bad"[1],
| but I don't now why the author thinks that.
|
| Also: my previous comment was wrong; you don't need
| "setopt short_repeat"; you only need it if you explicitly
| turned off short loops with "setopt no_short_loops".
|
| [1]: https://www.zsh.org/mla/workers/2019/msg01174.html
| darrenf wrote:
| For the first, I prefer range syntax: for i
| in {1..10}
| stouset wrote:
| Please please please always quote variable expansion. Just do
| it everywhere, every time. for i in
| "${foo[@]}"; do
| pjot wrote:
| To illustrate why, consider a file name with spaces.
| filename="my file.txt" cat $filename # Incorrect:
| Tries to 'cat' two files: 'my' and 'file.txt'
| cat "$filename" # Correct: Treats 'my file.txt' as one file
| mgdlbp wrote:
| Additionally, $ f=-x $ cat "$f"
| cat: invalid option -- 'x' $ cat -- "$f"
| cat: -x: No such file or directory # ^-- correct,
| but: $ f=- $ cat -- "$f"
| reading stdin... reading stdin... ^C
| $ f=./- $ cat -- "$f" cat: ./-: No such
| file or directory
|
| ...better to glob with ./* than *
| pjot wrote:
| Also for sanitizing user input. input=$1
| # User input, potentially dangerous rm $input #
| Incorrect: Risky if input contains something like '*'
| rm "$input" # Correct: Safer, treats the user input as a
| single item
| akho wrote:
| Or use Fish.
| rockwotj wrote:
| Or python...
| fragmede wrote:
| python is unbelievably awkward for shell scripting though
| vlovich123 wrote:
| I think with the cmd package it's not actually that bad
| and quite ergonomic. Ymmv
| shmerl wrote:
| True, true. I don't worry about it for explicitly simple
| indexes because too many quotes are ugly. But in general
| it's completely right.
| madeofpalk wrote:
| "Just remember how to do it" isn't really the problem.
|
| It's that the finer details of the syntax is sufficiently
| different from other things I do, and I don't write shell
| scripts frequently enough to remember it.
| doubloon wrote:
| exactly. i predict some kind of 'chat gpt shell' in the
| near future.
| cube2222 wrote:
| GitHub has already released this a couple months ago:
| https://docs.github.com/en/copilot/github-copilot-in-the-
| cli...
| mgdlbp wrote:
| zsh, short loop: for i in {1..10}; <<<$i
|
| powershell: foreach ($i in 1..10) { $i }
| 1..10|%{$_}
| xorcist wrote:
| > For iterating over an array:
|
| Bash array syntax is error prone and hard to read, and the
| expansion of arrays still depend on the field separator and
| must fit in the environment.
|
| Most of the time you should just rely on that field separator
| and do it the simple way: for i in "$f"; do
| echo $i; done
|
| Much more obvious and more shell-like. That's how all bash
| functions process their parameters.
|
| Set IFS only if you really need to. But in that case also
| consider something like xargs where you are not limited by
| environment, have null terminated fields, and offer
| parallelism.
|
| Arrays are only useful when you need multidimensionality, at
| which point you should probably look at using data files and
| process with other tools such as sed. Or start looking at
| something like Perl or Python.
| capableweb wrote:
| > 1. It's amazing that they're doing this as a gradual C++ to
| Rust rewrite, while keeping it working end-to-end, if I
| understand correctly.
|
| Seems to me they're not doing it gradually at all.
|
| > Another thing:
|
| > We plan on not doing any partial-rust release.
|
| > That means we would be doing e.g. fish 4.0 as fully rust and
| zero C++, and I think, contrary to what we usually do that
| warrants a beta. (Ordinarily we've stopped doing betas and
| release candidates because they simply don't get any testing).
|
| > We also still want to do a 3.7.0 in-between release that is
| still purely C++, so we have a better jumping off point for
| platforms that can't handle the rust version. It would be 3.6.1
| with some neat changes backported.
|
| https://github.com/fish-shell/fish-shell/discussions/10123#d...
| Cu3PO42 wrote:
| It's a bit of both. They are not doing any mixed C++/Rust
| releases, but you can check out the source and build it in
| the current mixed state and it will produce a binary that
| contains parts from both languages and works as a Fish shell.
| Animats wrote:
| The price of C++ compatibility is that it doesn't use Rust
| strings internally. It's all "wchar" and "WString", which are
| Microsoft C++ "wide character strings". This may be more of a
| Microsoft backwards compatibility issue than a C++ issue.
| cozzyd wrote:
| and yet they may be breaking Cygwin support?
|
| I think the problem is more like, there are valid files
| that aren't representable as rust strings?
| __jem wrote:
| That's why OsString exists.
| jshier wrote:
| The Cygwin issue isn't strings (well, that could be
| another issue) but that Rust doesn't support Cygwin in
| the first place, at least according to the comments in
| the linked thread.
| cozzyd wrote:
| Well, for whatever reason, it doesn't meet their
| requirements... See the String section of
| https://github.com/fish-shell/fish-
| shell/blob/master/doc_int...
|
| edit: here is a more specific rationale:
| https://github.com/fish-shell/fish-
| shell/pull/9512#discussio...
| giancarlostoro wrote:
| I still rather write Bash scripts or just bust out Python or
| Perl, but I definitely prefer Fish for terminal usage.
| jiripospisil wrote:
| More on the motivation behind the rewrite.
|
| https://github.com/fish-shell/fish-shell/pull/9512#issuecomm...
| silverlyra wrote:
| Wow, thank you for posting this. I've been kinda curious to try
| Fish over the years, but seeing this message from one of the
| maintainers - how mature and well-reasoned, how both charmingly
| joking and firmly assertive it is - now really gets me thinking
| that I've been missing out on using an excellent project.
| noobermin wrote:
| It is kind of telling that they thought porting to c++17 is
| "too much of a hassle" but rewriting everything in a new
| language isn't! Sorry, you're never ever going to beat "we did
| it to chase the new shiny" which is the story across the dev
| world.
|
| That said, I don't use fish and wish them the best
| coldtea wrote:
| > _It is kind of telling that they thought porting to c++17
| is "too much of a hassle" but rewriting everything in a new
| language isn't!_
|
| "Too much of a hassle" can mean "too much of a hassle in
| absolute terms" or "Too much of a hassle compared to what you
| gain". And porting to c++17 is probably high on the latter...
| stouset wrote:
| And this is quite literally the argument put forth by the
| maintainers. They _could_ upgrade to a newer C++, but it's
| a lot of hassle with few benefits.
|
| On the other hand they chose to port to Rust which is
| likely an even bigger hassle but comes along with a bunch
| of benefits that make planned future development
| significantly easier.
| trealira wrote:
| They said that they thought it wasn't worth updating from
| C++11 to C++17. In their defense, C++17 adds only some
| incremental changes. There isn't much to port anyway.
|
| Although I don't disagree with this:
|
| > _Sorry, you 're never ever going to beat "we did it to
| chase the new shiny" which is the story across the dev
| world._
|
| I don't think that's the case here. Rust offers more
| advantages over C++11 than C++17 or C++20 do.
|
| For people who don't want to find the relevant part of the
| original post, this is it:
|
| > _We moved to C++11 in 2016 (some quick calculation shows
| that 's 5 years after the standard was released), and we're
| still on C++11 because the pain of upgrading is larger than
| the promises of C++14/17._
| spacechild1 wrote:
| But why would they need to "upgrade" to C++17/20 in the
| first place? If you don't need any new features, you can
| just stay at C++11. (C++11 vs. C++98 is a whole other
| category.)
|
| So why exactly did they need to rewrite it in Rust?
| quchen wrote:
| > So why exactly did they need to rewrite it in Rust?
|
| The root comment links to a post literally about this,
| the post you're replying to lauded its content. Reading
| it sounds like a good idea. You can then still disagree,
| but the question you've asked is definitely answered
| there.
| spacechild1 wrote:
| You're right. I got confused by the C++17 "upgrade"
| argument (which doesn't make any sense to me).
|
| The following point made me laugh, though:
|
| > Being written in Rust will help fish continue to be
| perceived as modern and relevant.
|
| Is this tongue-in-cheek or meant seriously?
| cube2222 wrote:
| I believe it's meant seriously in that being written in
| Rust it's more likely to attract contributions from
| people doing it in their free time.
|
| I have only read the discussion when the rewrite was
| first proposed, but I believe that was mentioned as an
| advantage.
| spacechild1 wrote:
| > being written in Rust it's more likely to attract
| contributions from people doing it in their free time.
|
| Ah, because there are no Rust jobs? _duck_
| 3PS wrote:
| As someone who daily drives fish on ~4 different operating
| systems and loves it, I've been really excited about this rewrite
| and blown away by how fast it's been progressing given the size
| and complexity of the codebase. It will also somewhat lower the
| barrier to contributing for a lot of people, including myself.
|
| Another thing I'm very excited about, which has received less
| attention, is the planned future fish rewrite to use UTF-8
| instead of wchar_t (typically UTF-16). UCS2 and UTF-16 have been
| a plague on software and fortunately Rust makes working with
| UTF-8 a breeze.
| cpeterso wrote:
| > wchar_t (typically UTF-16)
|
| Complicating supporting multiple compilers in one code base,
| sizeof(wchar_t) is 2 bytes in MSVC (UTF-16) and 4 bytes in gcc
| (UTF-32).
| esafak wrote:
| Why, was the C++ codebase becoming unmanageable?
| theshrike79 wrote:
| Comment by the creator: https://github.com/fish-shell/fish-
| shell/pull/9512#issuecomm...
|
| tl;dr - string handling - threading
| - cmake issues
| darthrupert wrote:
| Becoming?
| DoctorDabadedoo wrote:
| I was raised in C++ spaguetti code bases, I didn't see a
| loved and well groomed project until I became a man.
| paradox460 wrote:
| Fish is such an underrated shell. They make some very strong,
| opinionated choices (like ditching POSIX compatibility), and the
| end result is an extremely nice shell. I've been using it for a
| bit over a decade now, and still love it.
|
| Fish shell scripting is also extremely pleasant to write, it
| feels like an ergonomic bash.
|
| There are a few warts, as with any project, but none of them have
| ever actually ever blocked me from just getting what I wanted
| done.
| thowaway91234 wrote:
| I love fish. Switch from ZSH+Prezto to just plain Fish and I'm
| not missing anything and it's way faster. All the servers have
| bash and I still write bash scripts, but for day-to-day terminal
| stuff it's Fish all the way for me.
| asylteltine wrote:
| I'm glad rust is replacing legacy languages like C and C++. It's
| time to stop using memory unsafe language ffs!
| exxos wrote:
| So, what new features do we get from that? Except that it doesn't
| work on Windows any more?
| jenadine wrote:
| Never worked on Windows. The programming language has nothing
| to do with that anyway.
| exxos wrote:
| It does.
|
| With Go, it would have worked out of the box on all the
| targets Go can support.
| Cu3PO42 wrote:
| > It does.
|
| It works in Cygwin right now, it doesn't work on Win32
| without a compatibility layer. Personally, I don't think of
| that as "working on Windows", but I concede that that's
| somewhat up to interpretation on the "on Windows" part. I'm
| confident that someone is going to get a MingW build
| working even if it's not official.
|
| > With Go, it would have worked out of the box on all the
| targets Go can support.
|
| That's absolutely disingenious. If you choose to only use
| the Go standard library , sure. But the same is true for
| Rust and even for C++. If you don't use any platform-
| specific APIs most languages will work on any target. Fish,
| however, does use platform-specific APIs and nothing about
| Go changes that.
| dymk wrote:
| unless you have to deal with OS specific APIs around
| process management and tty input, which is the bulk of what
| makes a shell challenging to implement
| ianschmitz wrote:
| As someone who uses zsh + spaceship, what benefits would I gain
| moving to fish as my main shell? I don't write many bash scripts
| so the scripting side is less of a concern.
| tipsytoad wrote:
| Eh, you can probably get very similar to fish with zsh + loads
| of plugins, but fish has lots of niceties out of the box
| (syntax highlighting, autosuggestion based on your directory).
| I've been using fish + starship with just a fzf plugin and it's
| got everything I need.
|
| Check it out, it's effective with very little config
| ilaksh wrote:
| For me it's really about the autocomplete.
| DoctorDabadedoo wrote:
| Tbh, little, mostly convenience (best metaphor I can give is
| installing Sublime Text vs manually installing your vim and
| your own personal configs). By default it supports a bunch of
| interesting things, autocomplete, iteractive filesystem
| navigation, theming (I used oh-my-fish in the past, not sure
| how it is now), etc.
|
| I like it, I would love to run it as my main shell, but I just
| do too much scripting for my own good to hop on this wagon.
| MrJohz wrote:
| If you've already set up your zsh as you like it, I don't think
| there's a huge amount of benefit. The big benefit of fish is
| that it's pretty much the ideal shell, but straight out of the
| box, without configuration. Autocomplete just works, navigating
| the history is easy, it completes commands from your history,
| choosing a shell prompt can be as simple as opening a browser,
| etc. You can customise it pretty much as deeply as you need to
| - just like zsh - but the defaults are good enough that you've
| got a really nice shell out of the box.
___________________________________________________________________
(page generated 2023-11-26 23:00 UTC)