nindalf
ivanjermakov
I'm surprised Rust took more lines. Perhaps formatter makes shorter lines due to method chaining? Or improved test suite?
duckerude
According to the blog post (https://fishshell.com/blog/rustport/#fn:formatting):
> A lot of the increase in line count can be explained by rustfmt’s formatting, as it likes to spread code out over multiple lines [...] The rest is additional features. Also note that our Rust code is in some places a straight translation of the C++, and fully idiomatic Rust might be shorter.
dartos
Rust, IMO is a noisy language. So not surprising it took more lines.
Having to handle every case of every branch also probably balloons line count.
Efficient LOC is not a goal of rust at all anyway.
Cthulhu_
Efficient LOC shouldn't be a goal or metric anyway, readability trumps conciseness... except when conciseness improves readability.
darthrupert
So is C++ though. But the "wasteful" (in terms of vertical space) formatting does indeed explain the difference.
nicce
Rust code defenitely takes more space with default formatter settings if you use functional paradigms. Every chained function call in many cases is one extra line. Default line width is not much anyway. Also if you handle all return types, lines will add up.
Since there are quite many contributors, it can be difficult to introduce some advanced macro requirements for the project, which could reduce the code.
yencabulator
Beyond what others have said about superficial things like laying out code differently, remember that Rust encodes memory-safety-related information in types, function signatures etc that might not exist at all in a C/C++ "we hope you do it right, or it's UB" codebase.
Also, here's a code size tracker that counts tokens not lines, which is a better measure: https://github.com/rrethy/tcount
bonzini
First experiences with QEMU suggest ~10% more lines of code.
kccqzy
Not surprising to me. While learning Rust, I rewrote in Rust several existing programs I had written in C++ and all of them were longer with default formatting.
abound
The most interesting thing about Fish 4.0.0 for most people will be that it is now written in Rust, which they talk about here [1]. Looking forward to testing it out and seeing if there are any noticeable differences.
markstos
I'll be curious if it's faster.
robin_reala
It’s broadly the same speed currently, but the goal was always to do a simple port to start with, then iterate from there.
bjoli
Anecdote time: I did a test like this with a small hobby project of mine (c++). I ported it to rust and saw roughly a 25% speed increase because of some refactorings I was meaning to do for a long time. I then ported the rust code back to c++ and saw another 15% gain in performance. Backporting the changes to rust again yielded no significant difference.
I am no rust programmer though, and I don't think the rust code was very idiomatic.
But then again I apparently write c++ like a common lisp programmer...
darthrupert
Faster than previous C++? Only if there were actual performance bugs that they fixed while doing the port.
rootnod3
What makes you think so? The Rust compiler is able to instrument LLVM a lot better and provide it with a lot more info than C++ can. The borrow checker does a lot of the work there to for example keep things on the stack or do LSE or GSE and other optimizations. It isn't just about "oh, the rewrite allowed them to restructure things and optimize the algos". It is also that Rust due to its nature is able to be absolutely damn fucking sure that it can remove or optimize certain parts, whereas C++ can't in many cases.
enriquto
[flagged]
lolinder
In what way does fish being built with cargo affect you as (not even) a user? Were you fish-curious in that you were interested in becoming a contributor? Or do you make a habit of judging projects that you might be interested in using based primarily on their build system?
akdor1154
I dont like lisp but hackernews is still fine to browse?
dmd
Why would you care what it's written in at all, unless you plan to work on it yourself?
lytedev
The same reason you might care about the artist or producer of a song: its context generally implies certain characteristics you might associate and appreciate.
For example, most Rust projects use clap which provides really nice command line help menus and also have relatively good performance in general.
enriquto
> Why would you care what it's written in at all
Well, actually, it was the OP who said, literally, that "the most interesting thing about Fish (...) will be that it is now written in Rust"
t43562
In a sense why should anyone care about this article? It's a shell, why is rewriting it in Rust noteworthy?
arbitrandomuser
What does it matter which tool-chain they use . I can understand if the difference is it made it notably slower or they dropped some features because they couldn't get it done in rust . But purely as an end user why would it matter if it's written in rust or cpp ?
benrutter
What do you dislike about it?
enriquto
quadratic dependency encouragement
johnnyjeans
the only vcs it supports is git
xigoi
It encourages adding hundreds of dependencies to every project, taking up gigabytes of storage, making compilation slow and resulting in bloated binaries with potential vulnerabilities.
darthrupert
Everyone is entitled to opinions of course, but this is a rather weird one given how Rust's toolchain is the thing most people like most about it.
albertzeyer
> However, there should be no direct impact on users.
I find this quite impressive, that they rewrote the whole Fish core, but everything keeps working exactly in the same way (except very few minor things which change in only minor ways, which they list).
nicce
If they managed to keep all the bugs as well and not to reduce them, that would be especially impressive.
kccqzy
I don't feel this is impressive. In Big Tech companies it's common for a team to rewrite an entire microservice without having any impact on users. Sure, a lot of that is for political reasons and unnecessary from a business perspective, and perhaps is selfish from a promotion perspective, but it's done very often.
nticompass
As a zsh user, I've been meaning to give fish a try. I keep adding plugins to zsh to make it act like fish (like command autocomplete) that I might as well try and/or switch to it.
giancarlostoro
My only annoyance with fish is when I copy bash one liners and forget, and get errors or issues. Otherwise, fish is fantastic.
porridgeraisin
There's a nice way to halfway-fix that issue. It makes use of the fact that most bash commands that we copy are prefixed with a $ and a space. It also requires your terminal emulator to have a way to hook into the paste mechanism and edit the to-be-pasted text. To my knowledge, Kitty and iTerm both have this feature.
Basically, the terminal will replace each line of the pasted text that match (start with)
$ rest
with pbash 'rest_escaped'
or more elegantly \$ 'rest_escaped'
We will then define a function with either of these names in fish.This function will start (if not exists) a persistent background bash instance connected on both ends to FIFOs, with the same lifetime as your fish session. We then pass the `rest_escaped` to one FIFO, capture the output from the other FIFO, and echo it.
Because its a persistent session, stuff you copy that makes use of variables or bash aliases all Just Work. Being able to blindly copy-paste the entire bash codefence from a github readme.md is especially nice.
It all happens automatically after a one-time setup, and overall works pretty well for me. Here is a demo: https://i.imgur.com/HdqGkRk.png
This is the fish function
function \$
if not test -f /tmp/bash_daemon.pid; or not kill -0 (cat /tmp/bash_daemon.pid) 2>/dev/null
echo "Starting bash daemon..."
bash ~/scripts/bash_daemon.sh &
sleep 0.5
end
echo "$argv" > /tmp/bash_daemon_pipe &
while read -l line
if test "$line" = "###DONE###"
break
end
echo $line
end < /tmp/bash_daemon_out
end
And this is the bash script `~/scripts/bash_daemon.sh` #! /usr/bin/env bash
rm -f /tmp/bash_daemon_pipe /tmp/bash_daemon_out
mkfifo /tmp/bash_daemon_pipe
mkfifo /tmp/bash_daemon_out
echo $$ > /tmp/bash_daemon.pid
while true; do
read cmd < /tmp/bash_daemon_pipe
{ eval "$cmd"; echo "###DONE###"; } > /tmp/bash_daemon_out
done
xk3
This is nice! But you should probably use $XDG_RUNTIME_DIR or /run/user/1000 instead of /tmp
giancarlostoro
Wow! This is fantastic! I will have to set this up ASAP.
gitaarik
Same situation, but I have the feeling that eventually I'll like the customizatability of zsh more than the convenience of Fish because I'm already too opinionated in my own configuration, and transferring to Fish might be more of a hassle than a gain. But who knows maybe someday it will be easier to customize Fish to my liking, but for now the ecosystem doesn't seem to completely fit my needs.
dgregd
A question for people who have already switched to the fish shell: What is the biggest drawback of using fish? For example, you get accustomed to it on your system and then have to work with Bash or Zsh on your company’s server systems. And if I’m going to make such a big switch from Bash to fish, then why not switch to Nushell instead?
timlyo
I use Fish as a user shell everywhere I can and end up using Bash daily for scripting and on servers/VMs/containers at work, I've also been using Nushell a lot recently for personal scripts.
Biggest drawbacks for me is mixing up a few bits of syntax and some software doesn't ship Fish completion scripts, although I never write scripts in Fish which reduces the syntax I actually use.
In my opinion Fish is worth it just for the auto complete suggestions alone, but I also really like the way it handles editing config, it's sane default config, understandable error messages, and plug-ins.
Nushell is very nice, but I find it doesn't match the usability of Fish for interactive shells. Love it for scripts though.
iN7h33nD
Biggest drawback is unfamiliarity with the syntax, but that comes with time in my experience. I think the syntax is overall better and much better documented.
I switched to fish because for most interactive use case it’s so much better, without requiring any new muscle memory. I tried zsh at first but it winds up slow to get even close to where fish is out of the box. I still end up scripting in bash or sh for portability.
nu-shell won’t be available in as many places, and it looks to me like it would change paradigm in a way that would hinder working with bash or zsh over time. That’s just my 2c though as I have only briefly glanced at it and haven’t truly considered using it.
maleldil
The main drawback is that I'm used to all the goodness that comes by default and have to get used to how primitive Bash is when I'm forced to use it.
I also prefer fish's scripting syntax (and built-in utilities) over bash, and some people don't like installing fish to run my scripts.
Nushell is far from fish in terms of interactive usage, and I find the scripting language to be too unstable for writing scripts you want to keep in the medium term.
robin_reala
If you use Homebrew it’s not available there yet, but it’s being added. See https://github.com/Homebrew/homebrew-core/pull/209124.
apatheticonion
You can just get the binary from the github, it's just a single executable! Or compile it yourself with one command (cargo build --release)
Cthulhu_
That's fair but having a package manager manage all your dependencies makes maintenance and hygiene easier.
simon04
Nice, it has landed. Now I'm getting:
> warning: Could not set up terminal for $TERM 'xterm-ghostty'. Falling back to hardcoded xterm-256color values
chanux
It has merged!
m00dy
I recently built my own shell to better understand its complexity and how it works under the hood. I also implemented redirections and partial tab completion. While I get that writing a shell isn’t the easiest task, I still don’t fully understand why there are so many different ones. I’ve been using the default shell on macOS, and so far, it works just fine.
t43562
The original one (bourne) had a great number of limitations and yet as part of a standard it didn't see much change.
Everyone wanted something better and each person had an idea of what better was.
bash became quite common because it's a superset and its' offered by GNU whose other tools made up for many other deficiencies in the various commercial UNIX implementations.
Then FreeBSD and Linux made GNU stuff the default and that was a big boost.
I tried fish couldn't really be bothered to persevere. A lot of the things I didn't like about bash were because I hadn't understood various bits and the more I know the more I find it fairly powerful and it has a kind of consistency. I don't love it but I found myself suddenly disempowered with things like fish.
mamcx
I go another notch: Why are so many different ones with so little major changes.
If you experience the `shell` of FoxPro DOS or other tools you will see how poor are the ones we tolerate now. Is like we still live in the age of `ed`.
(I even remember one of this projects have the joke that is finally a `terminal for the 90s!` or something like. Shells in common use a very poor things!)
specialist
Yup.
Have you read Jef Raskin's The Humane Interface? It's an explainer and retrospective for his Canon Cat.
I want more of that foundation, vision, concept.
With the recent renewed interest textual user interfaces (TUIs), maybe this cycle we'll tact a little closer to that utopian future perfect omni-shell.
https://en.wikipedia.org/wiki/The_Humane_Interface
https://en.wikipedia.org/wiki/Canon_Cat
https://en.wikipedia.org/wiki/Jef_Raskin#Pioneering_the_info...
--
And another thing (I say curmudgeonly)...
bash (and csh), the progenator of all modern shells, is just one realization.
Iteration and refinement are double awesome. We're seeing crazy awesome new variants, like Warp.app, oil shell, fish, and so forth. Yea for evolution!
But I would also hope today's youngsters take a moment to review the genesis of all the modern ideas we now take for granted. From memory, in no particular order:
Engelbart's Mother of All Demos
Raskin's original vision for Macintosh
Nelson's Xanadu
Higgins art philosophy of "intermedia"
Xerox PARC
cybernetics
Atkinson's HyperCard
etc.
The founders had motivations, insights, and ideas. Necessarily limited or ignored by feasibility. It's worth understand their ideas directly, for better or worse, not just thru subsequent intepretations.With 60+ years of progress and gestation, surely there are even more tangents worth exploring.
weakfish
It’s actually fish that has that tagline :)
pseudalopex
Most people reading this didn't experience FoxPro DOS probably. Why not say more?
Philpax
The second half of this comment reaches the opposite conclusion to what I would have expected from the first half.
jitl
Some people like nice things
johnnyjeans
different tastes.
oersted
I've used Fish for many years, but frankly only for the great autocompletion. The streamlined theme/prompt system and oh-my-fish plugin management are quite nice too, but minor.
The rest of Fish features that are not bash-compatible are rather a pain, particularly environment variable management. In principle these features have a better design than in bash, but not that much better, and their use is infrequent enough to have to re-learn them every time. Unfortunately, they just end up being a minor inconvenience when you try to copy-paste setup instructions from docs, and I don't interact with these features otherwise.
rainingmonkey
It's the opposite for me; things that are intuitive in Fish would involve inscrutable magic incantations copied from StackOverflow in Bash.
If you only want to use Fish for the autocompletion though, you can! Bash is always still there alongside Fish, you can just open a Bash shell when you're copypasting instructions, or `bash $SCRIPT` any scripts.
oersted
That's fair, and that's why I'm happy to keep using Fish. I suppose that I'd just prefer a leaner package and more focus on core features, but it's still my preferred option.
It's just that I never find myself needing to do anything fancy in the command line. I just want it to be fast, ergonomic, beautiful and unobtrusive.
And I wouldn't say it's because my workload is any simpler, I'm a relatively senior computer engineer working on large-scale data engineering, LLMs, non-trivial webdev and some systems programming in Rust. And it's not because I use UIs more often either, I use the command-line as much as anyone.
I guess that I have more of a "RISC" approach to the command-line.
homebrewer
ZSH is pretty compatible and has great auto completion. The best thing for me is inline documentation (bash-completion only shows the list of available completions and you have to derive their meanings by yourself).
It's also much easier to write your own completion scripts than for bash. The syntax is relatively sane, although fish completion scripts are much cleaner than bash or ZSH.
Stick to plain ZSH to avoid losing performance on bloated mess like oh-my-zsh, add fzf to quickly dig through history and find files/directories, and it's really the best option we have.
linsomniac
This.
I've been using fish as my primary shell for a couple years, primarily for the autocompletion. I started off with some zsh plugins that made the shell TOO fancy (and slow). I'd really like to see it be compatible but with some compelling improvements, rather than having them be just incompatible. Every time I can't do $() or fi... But for anything slightly complex I'll drop back down to bash rather than figure out the fish way to do it, because those things are rare enough that I have a hard time keeping them in my head.
I guess I could ask an LLM how to do it in fish, but for things that I already have stuck in my head it's just easier to drop to bash.
BiteCode_dev
The better syntax used to be a selling point, but now with AI being able to generate any trivial one-liner and minor scripts you need on a day-to-day basics, have a bad syntax would only affect bigger projects, which I would not write in Fish shell anyway.
It's a hard sell.
tomsmeding
Generative AI might be able to generate them, but it's still on you to understand the result and check that it indeed does what you want. And with the sometimes very nuance- or foot-gun-rich syntax of bash, that's rather a significant burden, if you're not familiar enough with the syntax to write the script yourself in the first place.
do_not_redeem
Speak for yourself, but I would not want to be beholden to AI for every trivial shell one-liner. "Sorry boss, ChatGPT is down, I can't count how many *.txt files are in this directory. See you tomorrow!"
I'll take the better syntax, thanks.
nske
To be fair, even local, small language models fare pretty well in such things (both explaining and writing).
queuebert
Heaven forbid you read a man page. Even though Bash is weird, it's fully documented.
kibwen
Scripting languages are so dynamic, flexible, arcane, and subtle and the consequences for getting scripts wrong are so potentially catastrophic for a system that they are absolutely the last thing I would ever dare generate via LLM.
kccqzy
The great autocompletion is a great inspiration to me as well. It's intuitive in how it works and requires no user manual, although when you sit down to analyze it, it actually has some subtle states. It's such a great design that I essentially copied its UX to a web app I was working on: https://github.com/kccqzy/smartcal/commit/10d32d18d257d5093d...
ElectricSpoon
What I truly appreciate is the completion system from a dev perspective. Writing completions is comfortable. Even wrapping completions into other completions is fairly clean (e.g. sudo {cmd}TAB).
drcongo
Can I ask what you find difficult about the environment variables system in Fish? Personally I find it absolutely lovely to use.
sceptic123
When you don't use it all the time it's impossible to remember what all the flags are for. The names/scopes are also not helpful, I usually want universal, but think I want global because I don't remember there is a universal. And the thing I have to look up every time is how to set a variable for the current line.
I'm not saying these are hard things, to figure out. I just agree that they're hard to remember when you don't use them all the time.
drcongo
I don't know if this helps at all but you can use `export FOO=bar` in Fish, and the prefixing a line with an envvar should work the same as in Bash etc. like `FOO=bar echo $FOO`
guytv
Can someone from the team share how the dev coordination for the Rust migration was handled? I only see a single PR (#9512)—how was the work organized?
bitdivision
There's some context here: https://news.ycombinator.com/item?id=38423908
pbronez
The rustport blog post says they lost support for Cygwin because it's not a supported Rust target. Looks like there is a fork for this:
https://github.com/ookiineko-cygport/rust
There have been discussions about adding the target to Rust, but they have not been pursued:
faho
The rust cygwin target has been merged (in a different attempt): https://github.com/rust-lang/rust/pull/134999
pbronez
Nice!
yencabulator
Tab completing "car" to "blkdiscard" just because I don't happen to have "cargo" in that $PATH is pretty nasty. How do I force tab completion to prefixes only?
OptionOfT
`clear-commandline` is an interesting one. It's a struggle between Windows and macos to maintain some form of consistency, and I failed to use Karabiner properly.
I'll have to check later today what now the default `cancel-commandline` is set to.
Fish 4.0: The Fish Of Theseus (https://fishshell.com/blog/rustport/) is the full story of their rewrite from C++ to Rust.
Discussed on HN here - https://news.ycombinator.com/item?id=42535217 (906 points, 198 comments).
Highlights of the rewrite
- 1155 files changed, 110247 insertions(+), 88941 deletions(-) (excluding translations)
- 2604 commits by over 200 authors
- 498 issues
- Almost 2 years of work
- 57K Lines of C++ to 75K Lines of Rust 5 (plus 400 lines of C 6)
- C++–