News for hackers. Stuff that matters.
Re:Decoded: GNU Coreutils by version_five on Friday September 08, 2023 @06:37PM (#37440189)
Cool, I didn't know this existed. I think simple ones like `yes` can be very interesting just to see how the base code of a utility (that writes to stdout) is written.

https://maizure.org/projects/decoded-gnu-coreutils/yes.html

Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @07:03PM (#37440369)
here is a Go implementation for fun:

    package main
    
    import "flag"
    
    func main() {
       yes := flag.String("m", "y", "message")
       flag.Parse()
       for {
          println(*yes)
       }
    }
Re:Decoded: GNU Coreutils by dale_glass on Friday September 08, 2023 @07:10PM (#37440430)
Yeah, GNU yes could be about that simple but it's a good deal more complex to obtain the best performance possible:

https://www.reddit.com/r/unix/comments/6gxduc/how_is_gnu_yes...

Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @07:13PM (#37440458)
um, who cares? most times people are needing to use "yes" as part of a "configure" script or similar. even if GNU yes was 10 times slower, it would NEVER be the bottleneck in any situation. so whats the point?
Re:Decoded: GNU Coreutils by dale_glass on Friday September 08, 2023 @07:21PM (#37440506)
I presume somebody had a need, and scratched the itch.

With modern systems we can have 8 channel RAM and 128 PCIe lanes to feed a system stuffed with NVMe drives. The amount of throughput that can be obtained is nuts, and at that point all sorts of weird things can become an unexpected bottleneck.

This applies even in consumer systems. Suddenly your game loads far slower on a NVMe than it could because it never occurred to the programmer that instead of the disk, the JPEG decoder can become a bottleneck when you can read compressed data at 7 GB/s.

Re:Decoded: GNU Coreutils by eichin on Friday September 08, 2023 @07:35PM (#37440600)
a decade or so ago, I ran into a problem where "yes" was already too fast, feeding it to apt-get install or something (in a context where we knew what the prompts were doing and if anything unusual happened we'd fail other checks immediately) and it had some clever input buffering going on... that wasn't clever enough and locked up on getting a megabyte of yes'es on the first read() call.
Re:Decoded: GNU Coreutils by shrubble on Friday September 08, 2023 @08:00PM (#37440817)
Check out 'stdbuf' perhaps?
Re:Decoded: GNU Coreutils by the-smug-one on Friday September 08, 2023 @07:20PM (#37440505)
You'll have to ask the author that. Now, I'd like to ask the author who cares how you implement 'yes' in Go ;-).
Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @07:22PM (#37440518)
yes C lines of code: 112

yes Go lines of code: 9

Re:Decoded: GNU Coreutils by placesalt on Friday September 08, 2023 @07:42PM (#37440661)
16 lines of go, with comments & whitespace
Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @08:13PM (#37440906)
134 lines of C, with comments & whitespace
Re:Decoded: GNU Coreutils by not2b on Friday September 08, 2023 @07:45PM (#37440689)
That isn't an apples-to-apples comparison. A C version could be similarly short, but the GNU yes implementer got carried away with efficiency considerations. If the Go program did the same, it would be longer.
Re:Decoded: GNU Coreutils by hunson_abadeer on Friday September 08, 2023 @07:45PM (#37440693)
It feels like you're making a bad-faith argument here. You can implement 'yes' in a straightforward way in a couple lines of C, too.

  main(int argc, char** argv) {
    while (1) {
      if (argc > 1)
        for (int i = 1; i < argc; i++) printf("%s%c", argv[i], (i == argc - 1) ? '\n' : ' ');
        else puts("y");
    }
  }
The point other folks are making is that it's written differently for a reason. Maybe not a reason that's important, but at the very least, let's try to compare apples to apples.
Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @08:09PM (#37440879)
I don't see include, which means you're ignoring warnings aren't printing them in the first place. Also testing against a number instead of boolean. Also you have a horrible hack instead of proper flag parsing. And you're also abusing brace elision just to reduce LOC. And again abusing ternary syntax for the same reason.
Re:Decoded: GNU Coreutils by rcr on Friday September 08, 2023 @09:35PM (#37441322)
Abusing? This is what ordinary C looks like
Re:Decoded: GNU Coreutils by mturmon on Friday September 08, 2023 @09:45PM (#37441376)
If you start with code golf, as you did, then this is where you end up. The only way to win is not to play?
Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @10:30PM (#37441635)
mine is just normal idiomatic Go code. thats not true of the C code.
Re:Decoded: GNU Coreutils by inferiorhuman on Saturday September 09, 2023 @02:42AM (#37442846)
It might be ugly, but that is idiomatic C code. C didn't even have boolean types until C99, and even then it's an "extension" of an integer type.

You could argue about the loop itself, after all K&R specified "for(;;)", but the other commonly used (ergo idiomatic) infinite loops use precisely the same number of lines. "while(1)" is a perfectly idiomatic manner to create an infinite loop.

Likewise a void return type for main was entirely legal until C99. The BSD yes(1) I've laying around only prints the first argument, so flag parsing? What flag parsing?

Yes in nine lines of C inclusive of preprocessor macro invocations and white space.

  #include <stdio.h>
  
  int main(int argc, char **argv) {
    const char *phrase = argc > 1 ? argv[1] : "y";
    while (1) {
      printf("%s\n", phrase);
    }
    return 0;
  }
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @08:40AM (#37444660)
I don't see proper flag parsing, I see an argv hack.
Re:Decoded: GNU Coreutils by inferiorhuman on Saturday September 09, 2023 @09:00AM (#37444845)
There are no flags in yes(1) ergo there's no need for "flag parsing". yes(1) takes one optional string as input, and that's exactly what argv provides. I'm not sure what you think "flag parsing" is bringing to the table here, but checking the array of command line parameters and accessing an element is pretty far from a hack.

If it's more comfortable you can also declare argv as an array of character arrays e.g. char *[], but that won't change the line count.

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @09:21AM (#37445050)
It's a lose for C either way. Either it cant parse flags, or we remove that requirement, and my code goes from 9 lines to 6.
Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @10:53AM (#37446099)
Who cares though? We get it, you prefer golang, congrats?
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @11:54AM (#37446791)
I am not seeing a technical argument here against the previous points, only one against the commenter:

https://wikipedia.org/wiki/Ad_hominem

Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @12:11PM (#37446983)
But you're also arguing in bad faith. Your go code is shorter, okay, but it doesn't do the same thing as the GNU yes code, so what point are you trying to make? I can also link to philosophy 101 wikipedia articles:

https://en.wikipedia.org/wiki/Straw_man

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @12:37PM (#37447258)
I think I have made it pretty clear already, but here it is again:

the Go code has MORE functionality (flag parsing) with LESS code. yes its not as fast, and yes the executable is larger, but for many, thats a good tradeoff for the extra standard library features, and the reduced LOC/code complexity. sadly as of yet, I haven't seen any cogent technical arguments against my points thus far.

Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @12:49PM (#37447384)
For an extremely simple utility like the 'yes' command that is compiled and distributed as a binary to trillions of installations what metric do you consider more important, size and speed? Or lines of code in the source? Think about this in engineering terms, everything is a tradeoff and it's your job to come up with the best solution.

I'm genuinely curious to hear your argument.

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @01:00PM (#37447512)
> I'm genuinely curious to hear your argument.

previous comments have demonstrated this not to be the case, so I will stand by my previous points. I have already made over 10 comments on this one topic, so if any aren't already convinced, they never will be, either because they disagree with the tradeoff, or they just have stockholm syndrome for C.

Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @01:16PM (#37447693)
You've demonstrated nothing and made no discernable argument to anyone. Best of luck in the job search my friend.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @01:22PM (#37447751)
I think anyone who has the ability to read and comprehend text would disagree with the comment I am replying to. Best of luck in the high school level reading class my friend.
Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @12:57PM (#37447467)
Also, take a look at openbsd's version of yes

https://github.com/openbsd/src/blob/master/usr.bin/yes/yes.c

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @04:24PM (#37449916)
more lines of code, and still doesn't have flag parsing
Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @04:43PM (#37450078)
There are no flags to parse. Why are you adding flag parsing? This would fail a junior interview Steven.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @06:42PM (#37451043)
when people resort to doxing, it shows how truly pathetic they are. I pity those people.
Re:Decoded: GNU Coreutils by rascul on Saturday September 09, 2023 @01:12PM (#37447650)
> the Go code has MORE functionality (flag parsing) with LESS code.

Your code does not have more functionality than GNU's yes as written. It's less code you have to write because of the flag parsing code that has already been written, and it's incompatible with GNU's yes because yours requires -m to change the message.

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @03:39PM (#37449495)
> Your code does not have more functionality than GNU's yes as written.

it has flag parsing

Re:Decoded: GNU Coreutils by rascul on Saturday September 09, 2023 @03:58PM (#37449662)
Which does not do functionally more than the C version that was shared by inferiorhuman.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @04:23PM (#37449911)
yes it does
Re:Decoded: GNU Coreutils by rascul on Saturday September 09, 2023 @12:08PM (#37446951)
The requirement to parse flags is your own. You can remove it from your go program. You only need to parse one string, if it exists.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @12:34PM (#37447211)
It's a lose for C either way. Either it cant parse flags, or we remove that requirement, and my code goes from 9 lines to 6.
Re:Decoded: GNU Coreutils by rascul on Saturday September 09, 2023 @12:46PM (#37447355)
C can parse flags and there is no requirement here for it to parse flags.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @03:17PM (#37449267)
It's a lose for C either way. Either it cant parse flags, or we remove that requirement, and my code goes from 9 lines to 6.
Re:Decoded: GNU Coreutils by rascul on Saturday September 09, 2023 @03:37PM (#37449463)
C can obviously parse flags. See for example the plethora of C software that does so, such as many things from GNU Coreutils.

There is no requirement to parse flags for the basic functionality of yes. You implemented that yourself. You can remove your own requirement whenever you want. You don't need to parse a flag, at most you need to parse a string from the command line arguments.

I wonder at this point how you define "flag".

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @03:39PM (#37449485)
It's a lose for C either way. Either it cant parse flags, or we remove that requirement, and my code goes from 9 lines to 6.
Re:Decoded: GNU Coreutils by moomin on Saturday September 09, 2023 @06:29AM (#37443860)
I mean, yes, go has proper flag parsing as part of the standard library and C doesn’t. Yes that’s going to make a line count difference but it’s also why code golf arguments are pointless.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @08:36AM (#37444608)
> go has proper flag parsing as part of the standard library and C doesn’t

That's the whole point. Every single command line program needs command line parsing. Go helps me get the job done, C forces me to write my own parser, or find some third party one.

Re:Decoded: GNU Coreutils by inferiorhuman on Saturday September 09, 2023 @09:04AM (#37444895)
Yes takes a single string with no embellishment, and that's what C provides. There's nothing additional to parse. There are no flags, no additional options, nothing else to configure… and that's by design as there's simply no need.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @09:19AM (#37445034)
It's a lose for C either way. Either it cant parse flags, or we remove that requirement, and my code goes from 9 lines to 6.
Re:Decoded: GNU Coreutils by inferiorhuman on Saturday September 09, 2023 @09:34AM (#37445224)
You can write a perfectly legible 4, 5, or 6 line version in C.
Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @09:37AM (#37445254)
OK I am waiting...
Re:Decoded: GNU Coreutils by moomin on Saturday September 09, 2023 @05:18PM (#37450387)
Yeah, but it’s horses for courses. The C version can be deployed in far more places and can be far faster than the Go equivalent. Which is “better” is a contextual judgement call. There’s plenty of weird architectures out there that run C and almost nothing else.
Re:Decoded: GNU Coreutils by staplung on Friday September 08, 2023 @08:20PM (#37440947)
On my mac the go version of yes creates a binary that's 30x larger than the yes binary I have on a linux machine. 2MB vs ~65KB.
Re:Decoded: GNU Coreutils by svnpenn on Friday September 08, 2023 @08:29PM (#37440988)
on mine it is 1,354 KB. I prefer the 10x LOC savings over a megabyte of hard drive, but you do you.
Re:Decoded: GNU Coreutils by BenjiWiebe on Friday September 08, 2023 @09:14PM (#37441221)
But if everything was written in Go it might be 1 megabyte * the number of users of coreutils. Might be worth using a few more lines of code to save a little bit of space on a lot of machines.
Re:Decoded: GNU Coreutils by commonlisp94 on Friday September 08, 2023 @10:47PM (#37441737)
It's not about hard drive space, it's about start up time.

The 10x LOC (despite being a huge exaggeration) is also the fixed cost, not the marginal cost. You're only forging main loop and includes, not any fundamental complexity.

This is also a funny argument coming from a Go programmer considering that Go trades off conciseness and expressivity for simplicity. Show me some of your favorite Go and I'm sure we can replace it with some concise C++.

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @02:22AM (#37442762)
> C++

I just physically shuddered

Re:Decoded: GNU Coreutils by commonlisp94 on Saturday September 09, 2023 @02:47PM (#37448899)
I bet you did.
Re:Decoded: GNU Coreutils by smashed on Saturday September 09, 2023 @12:38AM (#37442341)
This.

In fact, most embedded Linux thingy will be running the busybox version of core utilities instead of gnu coreutils for binary size reasons.

I other words, even gnu coreutils is too big.

Re:Decoded: GNU Coreutils by IshKebab on Saturday September 09, 2023 @08:29AM (#37444550)
Right but that's mostly because it includes its runtime and the C version does not.

It's pretty easy to avoid this problem anyway - just combine multiple tools into one binary like Busybox does.

In any case the simplicity of the Go code is not really related to the binary size.

Re:Decoded: GNU Coreutils by singron on Friday September 08, 2023 @08:19PM (#37440936)
I've heard before that a lot of GNU programs are stretched like this so that they don't resemble anything from proprietary AT&T unix. E.g. all the extra options in basically everything and the ridiculous optimization of things like yes.
Re:Decoded: GNU Coreutils by SubjectToChange on Sunday September 10, 2023 @06:52AM (#37454665)
I remember reading that the GNU project was rather keen on avoiding and removing artificial restrictions. In other words, if a feature was useful and reasonable then it should be seriously considered for inclusion. As for the aggressive optimizations that are sometimes seen, I assume it’s just people wanting to improve a tool that’ll be used everywhere, more for fun and/or notoriety than anything else.
Re:Decoded: GNU Coreutils by fipar on Friday September 08, 2023 @08:36PM (#37441033)
I'm not saying this is the reason, but unnecessary (or sometimes dangerous if used in real life) optimizations have been created to speed up QA runs (of course, that only works if what you optimize away is not part of what you're trying to test), e.g., libeatmydata.

But for 'yes', I'd agree with you, though I guess the answer to "who cares?" is that whomever wrote it cared. They could have a legit performance reason or may just have done it to show they could.

Re:Decoded: GNU Coreutils by rcr on Friday September 08, 2023 @08:45PM (#37441078)
Because you can't imagine a case its needed it must not exist? I also remember being a junior dev who thought they had all the answers.
Re:Decoded: GNU Coreutils by 38 on Friday September 08, 2023 @10:32PM (#37441646)
gotta love junior devs pretending to be more than, then calling out what they think are other junior devs
Re:Decoded: GNU Coreutils by pixelbeat__ on Friday September 08, 2023 @08:57PM (#37441140)
I optimized yes because:

* The fast version is still simple enough

* The general functionality being provided is to output arbitrary data repeatedly, and it can be useful to do this as fast as possible

Re:Decoded: GNU Coreutils by sltkr on Friday September 08, 2023 @07:08PM (#37440417)
Here's a Brainfuck implementation:

    ++++++++++[->++++++++++++>+<<]>+[.>.<]
(Unfortunately, Brainfuck doesn't support command line flags.)
Re:Decoded: GNU Coreutils by Cloudef on Friday September 08, 2023 @08:19PM (#37440939)
[.>.<] かわいい
Re:Decoded: GNU Coreutils by Twisol on Friday September 08, 2023 @10:18PM (#37441563)
(for those who can't read Japanese, and at risk of over-explaining, the parent called part of the program cute.)
Re:Decoded: GNU Coreutils by rcr on Saturday September 09, 2023 @05:29PM (#37450470)
Fyi before anyone else decides to read the idiocy that follows in this thread, this is guy is a known troll with a long history of this exact behavior. Same person:

https://news.ycombinator.com/item?id=27862463

I think this person is just mentally ill unfortunately.

Re:Decoded: GNU Coreutils by 38 on Saturday September 09, 2023 @06:47PM (#37451076)
when people resort to doxing, it shows how truly pathetic they are. I pity those people.
Re:Decoded: GNU Coreutils by version_five on Friday September 08, 2023 @08:32PM (#37441003)
Replying to myself because the thread got trolled:

My point was in part that it's valuable for even a simple utility to be well written and optimized and that it's nice to have these minimal examples to learn about how to, e.g. write output very quickly. The program is so short that presumably the number of lines is unimportant, and if the author knows how to do it they might as well make it as fast as possible so it's never in the way, and so we can learn from it. That's why I think it's a good example.

Re:Decoded: GNU Coreutils by m1keil on Friday September 08, 2023 @10:03PM (#37441474)
also quite interesting to compare with other implementations from the present and the past:

https://github.com/openbsd/src/blob/master/usr.bin/yes/yes.c https://github.com/freebsd/freebsd-src/blob/release/4.0.0/us...