Hacker Newsnew | past | comments | ask | show | jobs | submit | collinfunk's commentslogin

Only GNU sort uses threads. There is still some room for improvement there, if anyone wants to take a shot at it. :)

I think I saw the Rust based implementations sometimes used a separate thread for background tasks like statistics reporting. Not much additional in the way of "directly" using threads, but I wonder how many could actually be any faster with direct threading.

Canonical hasn't contributed anything to GNU coreutils in the time since the switch was announced, just to be clear.

I don't think sudo-rs ever advertised itself as a drop in replacement. They seem pretty upfront that it isn't their goal. See this list:

https://github.com/trifectatechfoundation/sudo-rs#difference...


Its not that if they have advertised themselves as a drop-in replacement or not. What made me bummed that cannonical used it as drop-in replacement and it did break some of my installation scripts.

Most of them are TOCTOU races or improperly following symbolic links. For example, uutils mkfifo(1) would create a world-readable and writable FIFO before using chmod(2) to restrict its permissions. Another user could replace that file with a symbolic link between the mkfifo(3) call and the chmod(2) to change the permissions of arbitrary files [1].

Other ones I find concerning are that you could also bypass '-- no-preserve-root' with a symbolic link to root [2]. Or by using paths equivalent to "/", e.g., "/../" [3]. Historically, GNU coreutils has been pretty good with symbolic links and avoiding TOCTOU races. The only notable one I can remember is a chmod(1) bug [4].

I agree with your general point that the number of CVEs is a useless metric, though.

[1] https://nvd.nist.gov/vuln/detail/cve-2026-35352 [2] https://nvd.nist.gov/vuln/detail/cve-2026-35349 [3] https://nvd.nist.gov/vuln/detail/cve-2026-35338 [4] https://github.com/coreutils/coreutils/commit/425b8a2f534fe0...


You can use equivs to create a dummy coreutils-from-uutils package, as mentioned in the responses to that report.

It is frustrating that Canonical has no interest in fixing it, though. It makes it hard to take their claims seriously that you can still use GNU coreutils if you want.


You're specifically frustrated about unbounded stack recursion exhausting the stack, triggered by multiple thousands of directories? It doesn't sound like this is about multi-thousand-deep directory structures, it sounds like it's about something else.

Because even diving into it, I would agree with a prioritisation decision that puts this bug down the bottom of a priority list.


This isn't the first issue with uutils.

Canonical is just rushing the switch because they want to get rid of software with GPLv3 license, not because there is any technical merit for doing so.


If they want the default to be non-GPLv3 Rust-based that's fine, but some of us don't care (and want the same behaviour everywhere, like on RH-based systems we may also have) and they should leave the GNU as an option. Potentially both could be installed at the same time (it's what update-alternatives is for after all).

That would work, but they also don't want everybody to switch to the better alternative and nullify their effort.

That's a better thing to discuss, and I'd expect there to be better bugs to talk about to go with it. Stack exhaustion in an unrealistic environment should be fixed, but a "stop everything" bug it ain't.

Legacy is a bit harsh...

FWIW, Canonical did not reach out to any of us who maintain GNU coreutils before, after, or during the transition. Had we known, we could have easily warned them about the incompatibilities.


Yeah, shouldn't have called it legacy, perhaps OG would have been more appropriate.

I really don't understand why Canonical rushes this. If 'rm' can't remove all possible directory entries, that is a big issue:

  $ podman run --rm -it ubuntu:26.10
  $ apt update -y; apt upgrade -y
  $ rm --version
  rm (uutils coreutils) 0.10.0
  $ gnumkdir -p $(yes a/ | head -n $((32 * 1024)) | tr -d '\n')
  $ rm -rf a
  Segmentation fault (core dumped) rm -rf a
  $ ls a
  a
  $ gnurm -rf a
  $ ls a
  ls: cannot access 'a': No such file or directory

I tried switching a buildroot based CI server to the 26.04

One Makefile statement triggered a bug in rust ln:

  src/%:
      @ln -sfn $(DIR)/foo src
In parallel build, we would get random failure:

  ln: Already exists
Rewrote that Makefile to work-around it, and ended up with the same kind of bugs with parallel $(INSTALL) -D ...

Tried latest ubuntu 26.10 which supposedly fixes a lot of TOCTOU races in rust coreutils, but no better.

Gave up and switched back to original coreutils.


but it segfaulted in a memory safe way.

sarcasm detected here :D

Rush? This is an interim release (95% or so only tracks LTS's) that is not even out yet... Go file a bug reports if you have some time.

The bug report I filed several months ago hasn't been looked at. Many of these utilities were released and made the default for Ubuntu 26.04 LTS!

There's a whole load of basic bugs reported and ignored:

https://bugs.launchpad.net/ubuntu/+source/rust-coreutils


They eventually fixed the one where it didn't sort properly, but it tooks months: https://github.com/uutils/coreutils/issues/12253 https://github.com/uutils/coreutils/issues/12912

I did, and the original dev of the component fixed it within a few days. It was straightforward, a backwards reading of a spec, reordered.

The fix is still sitting unmerged many months later.

This surprised me since I thought the project was in heavy bugfix/compat mode. I won’t touch it until I see some velocity on open bugs.


Fork Ubuntu and threaten their business model, that’ll get their attention.

Only half joking.


Ubuntu is the fork; just use Debian.

My solution was to stop using Ubuntu and move to Debian.

And in that debian install rust unix coreutils as default

There's very little incentive to switch. When people release for Linux they almost always first/only test it works on Ubuntu - hence it's going to be the least buggy. (ex: GOG only seemingly tested games on Ubuntu)

So the switching cost is buggy software. You'd need something radically different that brings enough new features to the table to make it worth it the switch and dealing with bad/non-existant support.

I think something like Nix/Guix but with stable library versions that matches Ubuntu/Debian LTS ones 1-to-1 could get traction


Then you would have to embrace their bad decisions, such as this one, and if you do, what’s the point?

Everything just needs to run from a container with their expected runtime environment.


Embrace the lock-in.

There are plenty of Ubuntu forks?

This is certainly not just affecting interim releases. Ubuntu 26.04.1 has been released but is currently held back from do-release-upgrade for the LTS channel (which IIRC is unusual for a LTS's .1 release) due to rust-coreutils issue:

> Users of Ubuntu 24.04 LTS will be offered an automatic upgrade to 26.04.1 LTS via Update Manager a couple of weeks following this release after some planned backports to address regressions in a recent version of rust-coreutils.

https://discourse.ubuntu.com/t/ubuntu-26-04-1-lts-released/8...


I have. It has been an open bug upstream for years as well.

ok, that's concerning, if you post it here I'll vote for it (after confirming).

The Launchpad bug is https://bugs.launchpad.net/ubuntu/+source/rust-coreutils/+bu... .

The apparently related bug in the origin project is https://github.com/uutils/coreutils/issues/2949, filed back in 2022 and which sat unmoved for several years until, probably not coincidentally, almost the same time yesterday that this appeared on Hacker News.


This is what made me move away from Ubuntu. Use LTS and encounter issues with outdated packages? "Well duh, you're supposed to upgrade to interim releases if you need remotely up to date software". Use interim releases and encounter bugs? "Well duh, it's an interim release. Of course it's a buggy mess, nobody uses those"

Every Fedora release is intended to be solid and they come out twice a year.


I moved to Fedora from Ubuntu about a year ago for my laptop. My main motivation was not be defaulted to snap packages. I have had a great experience i.e it gets out of the way and it doesn't fall apart when I update stuff. I was worried about SELinux but find Fedoras defaults just fine and intuitive.

My experience is that filing bug reports to ubuntu is a complete waste of time. Not sure if it's different for paying users.

Reporting bugs before Ubuntu releases has never worked for me. They always land a bunch of major changes after the supposed "freeze" then they ignore all feedback because of the freeze. It's infuriating.

Glad to hear that I am not alone. I feel like launchpad is totally ignored most of the time.

To get a response on a buggy GNU coreutils patch of theirs [1], I had to mention it in a rust-coreutils bug months later...

[1] https://bugs.launchpad.net/ubuntu/+source/coreutils/+bug/215...


I've been a Ubuntu user for about 20 years, and I file bugs every now and then on launchpad. I don't recall any of them ever being fixed.

Maybe the bugs get traction if you have a service contract?

Best to file bugs directly to upstream, but that of course means you should try it on the latest upstream version and not whatever version ubuntu ships, so it's more friction.


Upstream for much is Debian, but of course Ubuntu forks from testing, and then modifies...

But if you can identify it as a bug in a version in Debian, that's a good place to file, as Ubuntu will get the fix eventually.


Reporting bugs _at all_ in Ubuntu has never worked for me.

It can fail blazingly fast!

It is Year of the Linux Desktop, not Year of the Linux Cli.

Let them first fix Snap.

There is no reason for anyone on any distro to use snap.

It will die so just leave it alone.


They need to kill snap ...

I think ubuntu wants to kill desktop linux. No other explaination of why they push firefox inside snap, which then proceeds to constantly crash, when firefox used normally works completely fine.

I haven't tried chromium but I presume it's the same issue.

At work I'm forced to use ubuntu and I placed snapd on hold and added mozilla's own apt repository to my configuration to get firefox.

At least in the past few months the dbus crashes (been using systemd on debian for several years just fine, this never happened) that render the system unusable and un-rebootable have stopped… I guess when my company will decide to upgrade to 26.04 there will be more instability and problems.


sandboxing a browser makes total sense. my firefox and chromium running as snaps never crashed a single time for as long as I can remember, and I use both every day, at the same time.

Both have performance issues when installed as snaps across my 24.04 and 26.04 machines.

I sandbox with firejail. There is no reason to use snaps. Also in firejail I never experienced a crash.

> never crashed a single time

I'm very happy for you. How does that help the people who do encounter issues?


Firefox installed as a snap feels sluggish to me. When I install a Ubuntu system, the first thing I do is to uninstall any snap and install the apt versions of things, possibly adding official PPAs or using Guix to install software.

why bother with ubuntu at all ? If you want ubuntu but without snap out of the box, Zorin is 1 option. Or if you also hate gnome, linux mint.

Indeed. Thought not in all cases I can decide what OS to use. An employer might prescribe which one to use. And any distro will be better than being forced to use Windows.

> I haven't tried chromium but I presume it's the same issue

No issues with snap Chromium.


Yes, please. Linux distros is better with macos approach. And making appimage first class makes a lot of sense.

Appimages are bloated and unreliable. You can't guarantee that your app will run on any machine because it might depend on different system libraries.

Flatpak uses shared stable runtimes that are the same everywhere and don't take up space more than once. It also comes with a native update system and sandboxing. Snap is the same thing but worse.


My problem with flatpak is that the underlying runtime has a limited lifespan. I used the Sublime Text 3 flatpak for many years, and it was deprecated a few months ago because the runtime it was using was no longer supported. This caused people to update the flatpak to Sublime 4, which is good, but I only have a license for 3. In the end I just downloaded the binary for 3 from their website, and it still just worked. Flatpak still doesn't save you from bitrot.

There's a project called "anylinux appimages" that aims to make the most compatible appimages. They also use DwarFS for faster opening and smaller file sizes.

See: https://pkgforge-dev.github.io/Anylinux-AppImages/


> Snap is the same thing but worse

IIRC Snap relies heavily on AppArmor for sandboxing, so on anything non-Ubuntu the sandboxing is non-existent.


AppImages do not work anywhere close to how macOSs .apps do, and even if they did the approach isn't correct for how things work on Linux.

I'll avoid it at this point anyway. The Rust coreutils is another reason for that. Snap, monetizing updates, telemetry, enough is enough.

Yup. After almost 20 years, I have had enough of their crap. All of my new machines are getting Debian. Can’t wait until I am free of Ubuntu.

But this is totally not a memory ownership bug! It's some other kind of bug!

It's entirely aisine and makes me avoid Ubuntu every time it is possible. And it is repeated offence, Ubuntu always tried to push the envelope in worst place and way possible

Ubuntu is free. But Canonical is for profit. In these cases "if you are not paying for the product, you are the product" applies.

Ubuntu users will test this. Once the problems are ironed out, other distros will follow.


to enable GPL free embedded Ubuntu, field tested on all platforms (because it happens to be the default).

And that’s why i keep ubuntu far from my computers…

yeah, this is a bug. And yes, it should be fixed. But I don't think it will affect many users, I mean who has a 32000 -evels deep directory on their system?

> But I don't think it will affect many users, I mean who has a 32000 -evels deep directory on their system?

When the GNU coreutils version doesn't have this bug and thus affects zero users, why should I bother with the Rust version?


AI agent needs , rust memory safety , wasm , parralel task

It's less about the specific issue and more indicative of bad/insufficient test coverage

What programmer or programming language can't iterate a loop more than 32000 times?!

When triaging an issue you have to prioritise. Do you fix a problem that affects 2-3 people or one that may affect thousands?

The point is that such bugs shouldn't exist in the first place.

Using recursion on unbounded inputs on a programming language that doesn't support that (which are most) is an extremely classical mistake that really should be known to all programmers, especially those of low level languages that care about safety.

Every time you call something recursively you should be thinking "how deep is this?".


> The point is that such bugs shouldn't exist in the first place.

That's true of every bug, but you don't have infinite time or manpower, so how do you prioritise?


By that logic, why even spend effort migrating from a known-working implementation to one which is known to have outstanding bugs that there isn't enough bandwidth to fix?

Fashion.

Hard to say, but there are legitimate reasons. One of which being they think Rust is growing while C is a shrinking language. Other could be safety (yes, yes the audit did surface bugs). Or even that having a single lib work seamlessly on Windows/Linux/MacOS/Redux/Web.

It's a stack overflow which means it's using recursion and for historical reasons that don't make sense any more, stacks are teeny tiny on 64-bit Linux - apparently only 8 MB on Linux! I'm not sure why they don't raise it to something reasonable like 4 GB. I guess because they want consistency with 32-bit? Maybe we can finally change it if/when they phase out support for 32-bit Linux. Apparently it might not be that far away:

https://lwn.net/Articles/1035727/


8MB is the default per-thread stack size from glibc, also seems to be the default "ulimit" from pam or the kernel, I'm not sure. So for the main/default thread (or if not using threads) the process can use setrlimit() and for threads it can use pthread_attr_setstacksize() to get bigger stacks if it knows it may need them.

8MB is pretty huge though; musl libc is famous for defaulting to much smaller per-thread stack size of 128KB (to avoid over-committing lots of memory when there are many threads - the main dev is really principled/opinionated on this topic, but again there are a few ways for applications to explicitly size their stacks as large as they need). Linux kernel threads get a bit less than 16KB!


8MB is huge compared to the stacks we used to have when address spaces were 32-bit, but it's tiny compared to how much memory we can actually make use of now. The only real argument I can think of for having such a small stack is that large stack usage is often indicative of an infinite recursion bug and it catches them earlier.

But I don't really buy that for the same reason most programming languages don't limit loops to 8 million iterations (or whatever) by default - it would make catching infinite loop bugs easier!

I say most, because I know of at least one language that did do that - QuakeC! It made lots of sense in that context though.


OIC. Rust doesn't guarantee optimizing tail recursion. How unfortunate for a language that's getting widespread adoption.

For what it's worth there's reasonably active [1] work on implementing opt-in guaranteed tail calls - but it's not particularly fast going. LLVM (the backend rust uses) needs better support for musttail (e.g. some architectures just don't support it [2]).

[1] https://github.com/rust-lang/rust/issues/112788

[2] https://github.com/rust-lang/rust/issues/153827

By-default guaranteed tail calls really isn't rust's style, because it means subtle changes (introducing a destructor, re-ordering code, etc) can change semantics without you realizing it. If you want to guarantee that a call can't allocate a new stack frame you should have to say it.


Not so familiar with this area, but isn't the existing behavior of implicitly creating new stacks more of a problem than implicit tail-call elimination? Seems the latter is a kind of compiler-level optimization, of which there are already many (I think) that change the semantics internally but guarantee the outward behavior stays the same.

But I can understand the preference for an explicit opt-in, to make clear that it is enforced and not assumed.


> implicitly creating new stacks

I'd argue that it's explicit - that's what a function call does and you don't have implicit function calls in rust.

> Seems the latter is a kind of compiler-level optimization, of which there are already many (I think) that change the semantics internally but guarantee the outward behavior stays the same.

What you're asking for here already exists. Tail calls might be optimized into not allocating extra stack frames, the rust compiler just doesn't guarantee that it will perform that optimization (and almost certainly won't when code is compiled without optimizations... for instance).

What people want is the semantic guarantee that the stack frame won't be allocated. Not just a compiler that often performs the optimization. Otherwise you can't be sure that your code will keep working with new compiler flags/versions/architectures/... You could say "whenever the code is the right shape we'll guarantee the optimization" (C++ famously did this for things like copy elision)... but now the shape of code comes with non-obvious semantic guarantees and that's not rust's style. Hence the proposal for a keyword instead.


I see it, certain algorithms need guaranteed tail-call elimination, otherwise they are too inefficient and must be manually unrolled or rewritten to avoid blowing the stack. So a compiler optimization that is "nice to have" is not good enough.

No algorithm requires tail-call elimination in a general-purpose language with imperative mutability. It's just another way to express iteration.

Sure, but mutual recursion might require `goto` for example. Or an explicit state machine.

I can see how it might require an explicit state machine (keep a mutable state number and switch over the inlined bodies of what could be functions), but I'm not seeing how it could require `goto`.

Are there more-complex relationships that might require it?


I meant it more in the sense that “you need one or the other” rather than “some cases require one and some other cases require the other”.

> because it means subtle changes (introducing a destructor, re-ordering code, etc) can change semantics without you realizing it.

No, it won't change semantics - if you say @musttail or similar, it will simply fail to compile if you, say, introduce a destructor - the semantics will not subtly change.


Incorrect. `become` does change drop order - https://play.rust-lang.org/?version=nightly&mode=debug&editi....

That's not implementing tail calls breaks things, that's bad design of implementing tail calls breaking things.

The whole idea of "let's change semantics to make it easier" is dumb.

If you want guaranteed tail calls, change your code until it works.


Uh, yes, if you guarantee the semantics only when the code explicitly opts in and not by default then semantics will not subtly change, that is the point of my comment

It's not a change in semantics of compiled code. It is only a change of whether or not the code will compile.

Guaranteeing an optimization that otherwise only might run is a change in semantics. The attribute doesn't allow (in any sensible language) the code to simply not compile because the optimizer doesn't feel like it today (or you compiled with -O0), it forces the compiler to not allocate a stack frame wherever the code fits the structure that makes that definitely possible and fails to compile wherever it doesn't (even if after other optimization passes it happens to fit a structure that makes it possible).

I don't think that's related? The bug alluded to looks something like

    function rm(node) {
        for (const child of ls(node))
            rm(child);
        unlink(node);
    }
and no amount of tail call optimization will save you here, because this isn't tail recursion. Of course you could rewrite it using an explicit stack + tail recursion, but then you might as well be using a while loop.

Do any widely used languages guarantee tail call optimization? It's a pretty niche feature.

Depends on how widely we consider Scheme and Raket adoption in CS curriculum.

Scala, ocaml, racket, clojure, zig.

For recursion only kotlin.

(For most of these only with syntax specifying it)


How interesting. I'd seen LISP(y) implementations like Scheme guarantee tail-call since recursion is a very common technique in that language family. But I didn't know Zig supported it.

https://ziglang.org/documentation/master/#call

They have an @call built-in that guarantees: always/never tail, as well as always/never inline. That's neat, I can see how that would be useful in various situations.


Rust ? Because of ... memory safety. /s

from a ground-up rewrite, in a memory safe language i expect at the very least

- A meaningful error

- not a segfault


That way of thinking just means it'll never be fixed

"The Linux philosophy is 'Laugh in the face of danger'. Oops. Wrong One. 'Do it yourself'. Yes, that's it." Linus Torvalds

The problem there is that this is exactly the class of bug that does not exist in GNU coreutils because of philosophy of that project. Non-existence of such bugs proves that the impementation is not copied from AT&T code.

It's complicated to do it yourself when upstream won't accept your code.

What approach would you suggest for priorisation of tickets?

Ideally there should have been no tickets at all if all that's happening is a program being ported to another language.

This isn't a port - it's a re-implementation without any use of the original source.

That's also not all that's happening. It's also making improvements like better internalization support, better error messages, and a small handful of other extensions.


I have had to tell them repeatedly to stop copying tests verbatim, including the original comments from GNU coreutils. So I doubt this is true, which is frustrating.

What's wrong with them using the coreutils tests?

If they followed the license nothing. My uninformed knowledge is that the rust based rewrite is MIT, the originals are GPL, and you can't include GPL code in a MIT licensed project without making it GPL.

> and you can't include GPL code in a MIT licensed project without making it GPL.

Why is that? The tests are not linked to the distributed binaries. You can also distribute project sources with mixed licenses.


But you should be able to use a GPL test suite on an MIT-licensed program (or even a proprietary one, without the program needing to be under the GPL.

Capitalism.

Nah, people should (and do) fix small issues as well as big issues. Lying about the scale of issues and calling them "big" when they aren't just leads to no ability to prioritize or evaluate.

Incidentally someone submitted a PR for this issue about 3 hours before the first comment about it in this thread - https://github.com/uutils/coreutils/pull/14554 (and 2 hours before this link was submitted to HN)


I mean, that should work... but you can see why that would be considered low priority right?

Wow! Memory safety and such... Reminds me when a friend of mine wrote in IRC long time ago: "Hmm, tail just segfaulted." When I asked "Are you on Hurd?" he just replied "Yes."

While I supported that idea of Rust coreutils, this your experiment showed me how bad it is. My results are totally different, but not what I expected (edited out long strings of "a/a/a" for brevity). I wouldn't call it stable...

  root@71a8c5a6c5e3:/# mkdir -p $(yes a/ | head -n $((32 * 1024)) | tr -d '\n')
  mkdir: File name too long
  root@71a8c5a6c5e3:/# gnumkdir -p $(yes a/ | head -n $((32 * 1024)) | tr -d '\n')
  gnumkdir: cannot create directory 'a/a/a/.../a/a': File name too long
  root@71a8c5a6c5e3:/# gnumkdir -p $(yes a/ | head -n $((3 * 1024)) | tr -d '\n')
  root@71a8c5a6c5e3:/# rm -rf a
  rm: cannot remove 'a/a/a/.../a/a/a': Directory not empty
  root@71a8c5a6c5e3:/# gnurm -rf a
  root@71a8c5a6c5e3:/# rm -rf a
  root@71a8c5a6c5e3:/#
And then they plan to move to a new Rust-based NTP. No comment...

I wouldn’t judge the ntpd-rs move from this. Have been running it for 9 months or so with a nts pool in ntp server mode on my pi5. Been rock solid.

Hi, this is not a one bug.when the change app flags not working or not happening. I was measured with bsd and busybox.

Note that STF did not fund GNU coreutils. They funded uutils.


Note, I am a co-maintainer of GNU coreutils. Whether that makes my opinion relevant, biased, or both, you can decide. :)

I really wished the documented their benchmarking methodology here, or at least cautioned the reader not to jump to conclusions based on the benchmarks shown.

GNU 'sort' performance can drastically be altered by the locale in use, the input, and the arguments given to the --buffer-size and --parallel options. GNU 'sort' is fairly conservative in how many threads it will use by default, and in my experience, much more so than uutils. This is because throwing more threads at 'sort' may make it faster (or may not), but also risks running out of memory. This is an issue with uutils, which is poor at deciding when to use external sorting:

  $ export LC_ALL=C
  $ for i in {a..z}; do yes $i | head -n $(numfmt --from=iec 512M) | tr -d '\n' >> input; done
  $ time sort input > /dev/null

  real 0m24.245s
  user 0m0.896s
  sys 0m19.161s
Here is the same command using the latest uutils commit compiled with 'make PROFILE=release':

  $ time uu-sort input > /dev/null
  Killed                     uu-sort input > /dev/null

  real 2m53.560s
  user 1m40.634s
  sys 0m59.847s
The process gets killed by the OOM killer. This is likely because uutils 'sort' decides to use 18 threads, instead of the 1 used by GNU 'sort'. I find it a bit frustrating that benchmarks are thrown out without any methodology or citations, because they are often trusted without question. These could be benchmarks from before uutils had localization, which was the case before 2025, and treated LC_ALL=en_US.UTF-8 as LC_ALL=C. In that case, of course it would be much faster than GNU coreutils, but it also means uutils would give you the wrong results for non-ASCII characters. There is, as shown above, much more considerations beyond speed that seemingly never get the time of day next to flashy benchmarks...


There’s none of those details because it’s an AI written article. It doesn’t even talk about the stuff it says it’s going to in the very first paragraph.


That's a really great point, and demonstrates a deep understanding of how AI is changing the landscape of writing online!


Did I just read an HN comment written by an AI? Looks sycophantic enough


I believe that is "The Joke"


You are absolutely right! It's not just that you spotted it, it's how you pointed it out that make your comment upvote worthy


changing the landscape of writi' you mean fucking shit up to the point of no return?


Hi, co-maintainer of GNU coreutils!

Is there any effort from the GNU organization to solve long-standing issues and pain points such as locales?

As it stands I am generally averse to using GNU tools because my feeling is that they will be slow, clunky and exhibit arcane behavior in particular edge cases. ripgrep is significantly faster than GNU grep -R; fd than GNU find, etc.

For example, before LLMs were common, I once had to spend an entire day getting GNU flex and GNU bison to generate code that was: a) properly prefixed with a custom prefix, not yy_ et. al and b) did not use global variables.

I would have understood if, for backwards compatibility, this was gated behind a --sane flag or similar, but the GNU manuals were, at least at the time, under the confusing impression that what I was doing was advanced usage and used semi-fancy terms like "re-enterant" to describe what should be the normal behavior. I had to toggle several different knobs, some working for macros, others for functions, and the knobs were different for flex and bison.

POSIX locales in particular are an anti-feature, and I say this as a non-English native, so uutils adding support for them feels like bug-compatibility with GNU, not feature-compatibility.

Other issues involve the dynamic linking requirements of glibc and of the nsswitch in a world that would increasingly prefer to link things statically.

I am really saddened if the reaction is just that GNU is the old and stable is the main argument here. Because when you read many GNU documents and manpages, written years ago, you get the feeling that the original authors were looking to do things properly, make breaking changes where they were sane (hence POSIXLY_CORRECT), innovate (Emacs), and overall would not have been particularly swayed by the "old and stable" argument of traditional Unix distributions at the time.

The Rust community seems to be the one making exciting innovative stuff nowadays. uucore is more complimentary as well, ripgrep and fd are much more interesting. Sure, there may be certainly kinks, as you pointed out. But Rust programs can be debugged. Can GNU programs innovate?


> Is there any effort from the GNU organization to solve long-standing issues and pain points such as locales?

Most GNU projects don't have a large overlap, if any overlap at all, between their active contributors. I suspect they behave far more independently than you expect. Also, GNU didn't invent locales, if that is what you are getting at.

> As it stands I am generally averse to using GNU tools because my feeling is that they will be slow, clunky and exhibit arcane behavior in particular edge cases. ripgrep is significantly faster than GNU grep -R; fd than GNU find, etc.

Those programs have their imperfections as well. Particularly, they don't account for arbitrary limits like PATH_MAX. See 'fd' stops before visiting the deepest directory without altering it's exit code:

  $ mkdir -p $(yes a/ | head -n $((16 * 1024)) | tr -d '\n')
  $ fd a | wc -l
  3119
  $ echo ${PIPESTATUS[@]}
  0 0
On the other hand GNU find can visit arbitrarily deep directories:

  $ find a | wc -l
  16384
ripgrep has similar issues:

  $ (while cd $(yes a/ | head -n 1024 |  tr -d '\n'); do :; done > /dev/null 2>&1; echo a > a)
  $ rg '^a$' a
  rg: a/[...]/a: File name too long (os error 36)
GNU grep handles this fine:

  $ grep -r '^a$' a
  a/[...]/a:a

> For example, before LLMs were common, I once had to spend an entire day getting GNU flex and GNU bison to generate code that was: a) properly prefixed with a custom prefix, not yy_ et. al and b) did not use global variables.

Flex isn't a GNU project. I don't use or contribute to Bison, but I am pretty sure that is here:

https://www.gnu.org/software/bison/manual/bison.html#Multipl...

> I would have understood if, for backwards compatibility, this was gated behind a --sane flag or similar, but the GNU manuals were, at least at the time, under the confusing impression that what I was doing was advanced usage and used semi-fancy terms like "re-enterant" to describe what should be the normal behavior. I had to toggle several different knobs, some working for macros, others for functions, and the knobs were different for flex and bison.

Again, I don't contribute to Flex or Bison. I also do not use them. However, I will note that understanding the programs require some complex topics, specifically formal languages and automata. I am not entirely surprised that some of the documentation can be a bit difficult to understand.

> POSIX locales in particular are an anti-feature, and I say this as a non-English native, so uutils adding support for them feels like bug-compatibility with GNU, not feature-compatibility.

They are also widely supported by other implementations. It would be harmful to everyone if we were to disregard them. Also, as I mentioned previously, they were not invented by GNU.

> Other issues involve the dynamic linking requirements of glibc and of the nsswitch in a world that would increasingly prefer to link things statically.

I am a committer to glibc, but this isn't really my area of focus. You are free to discuss it on libc-help@sourceware.org if you'd like.

> I am really saddened if the reaction is just that GNU is the old and stable is the main argument here. Because when you read many GNU documents and manpages, written years ago, you get the feeling that the original authors were looking to do things properly, make breaking changes where they were sane (hence POSIXLY_CORRECT), innovate (Emacs), and overall would not have been particularly swayed by the "old and stable" argument of traditional Unix distributions at the time.

We make breaking changes. I recently changed 'printenv' and 'env' to safely quote their output. I will note though that although you want us to make more changes like this, others get quite angry at us when we do. Even changes that aren't breaking cause angry mailing list messages. We can't make everyone happy.

> Can GNU programs innovate?

Individual GNU projects are free to innovate as much or as little as they want.


Thanks for taking the time to respond to all my points!

Unfortunately, I find this confirms all my fears.

Whether or not ripgrep, fd, sd, et al. have some bugs left in them or not, the fact remains, when they do work (which is 99%+ of the time for most users), they are significantly more pleasant to work with. More pleasant = more use = more eyes = the bugs get fixed in the long run (as GNU should know from it's history!).

I wish everyone all the best, but I really do see a lot of these tools going the way of X.org in the next 10 years. Or, more likely, the way of csh.

> However, I will note that understanding the programs require some complex topics, specifically formal languages and automata. I am not entirely surprised that some of the documentation can be a bit difficult to understand.

And it has every right to be, when it is discussing these topics. But not polluting the global namespace and not using global variables is not an advanced request!


When did this occur? I am a GNU maintainer, and have never heard such a thing from the FSF. The GNU Coding Standards and other similar texts leave the decision to support non-free platforms up to the maintainer.


It was an emoji solution for Emacs that only worked on Mac. RMS basically said:

"If the point is to promote Free Software, we do ourselves a disservice by making our Free Software work better on a proprietary system than a Free system. Let's include this support when it works on the Free platforms as well."

FSF is political, but only about Free Software. Their goal is to promote it, and I think RMS has shown very clear thinking in this regard. I don't love the decision/outcome (someone did work to make something better and it was rejected), but I get it in service of the larger goal.

To flip the pschology, you could imagine a world where Emacs did way more awesome stuff on Windows and Mac, and the ensuing HN discussion where the obvious snipe appears a dozen times: "lol they keep talking about free software but their own products work better on windows lol".


FSF is not political in the sense that they won't forbid you to use their software or otherwise blacklist you even if you are against free software, or if you're far left or far right. They are only political in the sense that they have a goal. If that's how you define "political" then the word is somewhat meaningless.

They won't take contributions not aligned with their goals but won't block you from sharing your contributions in the spirit of free software.


It was a while ago (20-ish years?) and I'm forgetting the details, but it was RMS and I think the package was emacs.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: