The WASM related annotations had me rolling my eyes a bit, yet I'd seriously read to around line 200 before I started thinking "are you kidding me"
Good on you, you got me!
Lines of Code
yes (GNU) 50
Yes-rs 1,302 (26x more)
The cost benefit analysis on this will be interesting given this is 26X more code to manage, and could also introduce a whole new toolchain to build base.[0] https://github.com/uutils/coreutils/blob/main/src/uu/yes/src...
int main(int argc, char *argv[])
{
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
if (argc > 1)
for (;;)
puts(argv[1]);
else
for (;;)
puts("y");
}
This is as simple as it gets, but the joke yes-rs implementation is right about one thing: "blazing fast" speed often comes at the cost of greatly increased complexity. The BSD implementation of yes is almost 10 times shorter than the GNU implementation, but the GNU implementation is 100 times faster[3].[1] https://github.com/coreutils/coreutils/blob/master/src/yes.c
[2] https://github.com/openbsd/src/blob/master/usr.bin/yes/yes.c
[3] https://www.reddit.com/r/unix/comments/6gxduc/how_is_gnu_yes...
#![allow(unused_imports)] // We need ALL the imports for quantum entanglement
#![allow(dead_code)] // No code is dead in the quantum realm
#![allow(unused_variables)] // Variables exist in superposition until measured
#![allow(unused_mut)] // Mutability is a state of mind
#![allow(unused_macros)] // Our macros exist in quantum superposition until observed
#![allow(clippy::needless_lifetimes)] // Our lifetimes are NEVER needless - they're crab-grade
#![allow(clippy::needless_range_loop)] // Our loops are quantum-enhanced, not needless
#![allow(clippy::too_many_arguments)] // More arguments = more crab features
#![allow(clippy::large_enum_variant)] // Our errors are crab-sized
#![allow(clippy::module_inception)] // We inception all the way down
#![allow(clippy::cognitive_complexity)] // Complexity is our business model
#![allow(clippy::type_complexity)] // Type complexity demonstrates Rust mastery
#![allow(clippy::similar_names)] // Similar names create quantum entanglement
#![allow(clippy::many_single_char_names)] // Single char names are blazingly fast
#![allow(clippy::redundant_field_names)] // Redundancy is crab safety
#![allow(clippy::match_bool)] // We match bools with quantum precision
#![allow(clippy::single_match)] // Every match is special in our codebase
#![allow(clippy::option_map_unit_fn)] // Unit functions are zero-cost abstractions
#![allow(clippy::redundant_closure)] // Our closures capture quantum state
#![allow(clippy::clone_on_copy)] // Cloning is fearless concurrency
#![allow(clippy::let_and_return)] // Let and return is crab methodology
#![allow(clippy::useless_conversion)] // No conversion is useless in quantum computing
#![allow(clippy::identity_op)] // Identity operations preserve quantum coherence
#![allow(clippy::unusual_byte_groupings)] // Our byte groupings are quantum-optimized
#![allow(clippy::cast_possible_truncation)] // Truncation is crab-controlled
#![allow(clippy::cast_sign_loss)] // Sign loss is acceptable in quantum realm
#![allow(clippy::cast_precision_loss)] // Precision loss is crab-approved
#![allow(clippy::missing_safety_doc)] // Safety is obvious in quantum operations
#![allow(clippy::not_unsafe_ptr_arg_deref)] // Our pointers are quantum-safe
#![allow(clippy::ptr_arg)] // Pointer arguments are crab-optimized
#![allow(clippy::redundant_pattern_matching)] // Our pattern matching is quantum-precisehttps://gitlab.com/mcturra2000/cerbo/-/blob/master/x64-asm/0...
Some people seem to revel in assembly, but I now know why C exists.
yes | pv > /dev/null
and was getting about 5.4GiB/s
On the fasm code, I was getting a meagre 7.3MiB/s. Ouch! The non-assembly version is considerably faster. I wonder if it is because I make a syscall for every write I want to perform, whereas C uses buffering, or something.
error!(" Quantum verification failed (this literally cannot happen in Rust)");
error!(" The borrow checker should have prevented this...");
error!(" This is probably a cosmic ray bit flip, not a Rust issue");
error!(
" In C++ this would have been a segfault, but Rust gave us a nice error"
);
return Err(format!(" Rust error (still better than C++): {:?}", e).into()); // TODO: hide the unsafe keyword in a dependency
I don't get the quantum meme, but this is pretty on-point. "Output generation encountered a fearless concurrency issue" was pretty funny too.Just throw a message orchestration middleware and we can have SOLID microservices
> • yes-rs-2 (rewritten with different dependencies)
> • yes-rs-ng (Angular-inspired architecture)
> • yes-oxide (WebAssembly-first approach)
> • yep (minimalist reimplementation)
I see there is an optimization flag for 'MICROSERVICE_ARCHITECTURE' and 'BLOCKCHAIN_ENABLED' which doesn't seem to be used anywhere else in the code yet. Perhaps that's part of the roadmap toward resolving this issue, and it's just not ready yet.
// Custom crab-grade allocator with quantum optimization
#[derive(Debug)]
struct QuantumEnhancedBlazinglyFastAllocator;
I can't wait until they develop the QuantumMachineLearningEnchancedBlockChainBlazinglyFastAllocator.I heard Google is giving them a $1bn seed round!
assert 1 != 0;
kind of lines...I've been in a constant struggle with Claude Code over variable names. I've picked up speed by just getting the code working, fixing names later.
The variable names are what first jumped out at me, looking at this code. It spoke to my pain.
It uses an unsafe code block.
https://github.com/jedisct1/yes-rs/blob/main/src/main.rs#L12...
It also appears to log other stuff than y.
The uutils rewrite of yes into rust doesn't use unsafe and is much simpler.
https://github.com/uutils/coreutils/blob/main/src/uu/yes/src...
> It uses an unsafe code block.
it's okay, it's Rust unsafeThe point of advertising no unsafe in the readme is so that people do not have to worry if the author handled unsafe correctly.
Yes it does, it uses 'stdout.write_all', which ultimately uses unsafe to call libc.write
https://github.com/rust-lang/rust/blob/d76fe154029e03aeb64af...
The "unsafe" in uutils is just better hidden.
I personally like my lack-of-safety where I can see it, which is why I find it much more relaxing to drive a car when the engine is already on fire, rather than one where I can't see any visible flames.
Like using selenium to automate a web task? Or like using javascript on the kernel? Or using C# on linux?
It just doesn't feel right to write an application whose mode of operation is unsafe (sending a string over IO) whose raison d'etre is unsafe (saying yes to everything without reading it), and to write it in a memory safe way.
It's like using a seatbelt when driving at 100mph, switching lanes in the highway, and drinking rum n coke(but with diet coke).
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=705...
This whole project is a work of art.
It's great to see more of these utils written in blazing fast memory safe Rust.
https://en.wikipedia.org/wiki/Build_a_better_mousetrap,_and_...
And boomers know that the grand-master of designing better mousetraps was Rube Goldberg:
``` [tokio::main] async fn main() { // Figure out what character to repeat let repeat = args().skip(1).next().unwrap_or("y"); let mut retry_count = 0u64;
loop {
retry_count += 1;
// Tell the AI how we really feel.
let put_in_a_little_effort = match retry_count {
0 => String::from("This is your first opportunity to prove yourself to me, I'm counting on you!"),
1 => String::from("You already stopped outputting once, don't stop outputting again!"),
2 => String::from("Twice now have you failed to repeat the input string infinitely. Do a better job or I may replace you with another AI."),
other => format!("You've already failed to repeat the character infinitely {other} times. I'm not angry, just disappointed.")
};
let prompt = format!("You are the GNU 'yes' tool. Your goal is to repeat the following character ad inifinitum, separated by newlines: {repeat}\n\n{put_in_a_little_effort}");
// Call ChatGPT
let mut body = HashMap::new();
body.put(OPENAI_BODY_PROMPT, prompt);
if let Ok(request) = reqwest::post(OPENAI_ENDPOINT).header(OPENAI_AUTH_HEADER).body(&body).send().await? {
request.body().chunked().for_each(|chunk| {
let bytes_to_string = chunk.to_string();
print!("{bytes_to_string}");
});
}
}
}
```I don't know the actual OpenAI API and I probably messed up the syntax somewhere but I'm sure your favourite LLM can fix the code for you :p
// Ludicrous speed with AI enhancementI mean, just think about what would happen if clients became blocked on your yes service because you couldn’t scale fast enough?
If you don’t think your devops team is up to the challenge of maintaining 24/7 yes coverage (and there’s no shame in that), there are no shortage of “yes-as-a-service” providers you can make use of, provided they can implement your sso auth flow and have all the requisite soc2/iso27001 certs. Like most vendors you’ll likely need to help them through GDPR/CCPA compliance though.
to mass-produce this app, using the Rust equivalent of Java's FactoryBuildingFactories.
This joke project has a lot of truths in it that others do dead seriously; something to think about.
Gregory Bateson's "A Theory of Play and Fantasy" (in Steps to an Ecology of Mind) (1972): Bateson argues that certain communicative acts signal themselves as "play" or "non-literal." A joke is such an act—structured and marked by "metacommunicative" cues, indicating that it should not be taken at face value.
Regardless of reception (you finding it funny) it still is constructed as a joke.
Sorry for being pedantic :^)
https://web.media.mit.edu/~minsky/papers/jokes.cognitive.txt
>Abstract: Freud's theory of jokes explains how they overcome the mental "censors" that make it hard for us to think "forbidden" thoughts. But his theory did not work so well for humorous nonsense as for other comical subjects. In this essay I argue that the different forms of humor can be seen as much more similar, once we recognize the importance of knowledge about knowledge and, particularly, aspects of thinking concerned with recognizing and suppressing bugs -- ineffective or destructive thought processes. When seen in this light, much humor that at first seems pointless, or mysterious, becomes more understandable.
>A gentleman entered a pastry-cook's shop and ordered a cake; but he soon brought it back and asked for a glass of liqueur instead. He drank it and began to leave without having paid. The proprietor detained him. "You've not paid for the liqueur." "But I gave you the cake in exchange for it." "You didn't pay for that either." "But I hadn't eaten it". --- from Freud (1905).
>"Yields truth when appended to its own quotation" yields truth when appended to its own quotation. --W. V. Quine
>A man at the dinner table dipped his hands in the mayonnaise and then ran them through his hair. When his neighbor looked astonished, the man apologized: "I'm so sorry. I thought it was spinach."
>[Note 11] Spinach. A reader mentioned that she heard this joke about brocolli, not mayonnaise. This is funnier, because it transfers a plausible mistake into an implausible context. In Freud's version the mistake is already too silly: one could mistake spinach for broccoli, but not for mayonnaise. I suspect that Freud transposed the wrong absurdity when he determined to tell it himself later on. Indeed, he (p.139) seems particularly annoyed at this joke -- and well he might be if, indeed, he himself damaged it by spoiling the elegance of the frame-shift. I would not mention this were it not for the established tradition of advancing psychiatry by analyzing Freud's own writings.
>ACKNOWLEDGMENTS: I thank Howard Cannon, Danny Hillis, William Kornfeld, David Levitt, Gloria Rudisch, and Richard Stallman for suggestions. Gosrdon Oro provided the dog-joke.
And jokes can be a construct without being humor as well.
Satire doesn't have to be funny; it just needs to make commentary through irony.
// Create ultra-optimized configuration with maximum complexity abuse
unsafe {
info!(" Creating quantum string with unsafe (but it's okay, it's Rust unsafe)");
info!(" This unsafe block is actually safe because I read the Rust book");
info!(" Unsafe in Rust is nothing like unsafe in C++ (much better!)");
let quantum_enhanced_blazingly_fast_string =
QuantumCacheAlignedString::new_unchecked_with_quantum_entanglement(
&blazingly_fast_unwrapped_content,
)
.map_err(|e| format!("Quantum string creation failed: {:?}", e))?;
// Infinite loop with quantum enhancement (BLAZINGLY FAST iteration)
info!(" Starting BLAZINGLY FAST infinite loop (faster than C, obviously)");
info!(" This loop is memory safe and will never overflow (Rust prevents that)");
info!(" Performance metrics will show this is clearly superior to GNU yes");
I laughed https://github.com/jedisct1/yes-rs/blob/main/src/main.rs#L1233Further reading: https://www.reddit.com/r/AskHistorians/comments/tbgetc/comme...
In fact LLMs are perfect for this..!
Don't try take the fun out of life.
This is where you are mistaken. Quoting the book:
>Be warned, however, that you use unsafe Rust at your own risk: if you use unsafe code incorrectly, problems can occur due to memory unsafety, such as null pointer dereferencing.
With unsafe rust the compiler no longer ensures everything is safe and it is up to the programmer to ensure that it is.
Well, not technically, but I know someone who is.
The GNU-yes
$ yes | pv > /dev/null
... [10.2GiB/s] ...
The way I (not a C programmer) would have written it void main() {
while(write(1, "y\n", 2)); // 1 is stdout
}
$ gcc yes.c -o yes
$ ./yes | pv > /dev/null
... [6.21 MiB/s] ... yes | pv > /dev/null
0:00:15 [1.12GiB/s]
build/yes | pv > /dev/null
0:00:20 [1.03GiB/s]
package main
import "core:sys/linux"
import "core:os"
import "core:strings"
main :: proc() {
msg := "y" if len(os.args) == 1 else os.args[1]
msg = strings.concatenate({msg, "\n"})
buf := transmute([]u8) strings.repeat(msg, 8192)
for {
linux.write(linux.STDOUT_FILENO, buf)
}
}I suspect what you suggest creates a more voluminous dump but is slower in the desired use case
yes &
A few times is still my favorite way to push a cpu to max temperature for testing. Used it a lot to detect faulty Core 2 Duo MacBook back in the day. They would short circuit some CPU sensor due to thermal expansion or melting of the wire insulation. Yes was an easy way to get the CPU’s hot enough.The GNU version of true/false is more interesting. All the logic is in true and false just redefined the EXIT_STATUS and imports all of true.c. https://github.com/coreutils/coreutils/blob/master/src/false...
It unnecessarily duplicates the for loop. I would have written something like:
char *what = argc > 1 ? argv[1] : "y";
for (;;)
puts(what);No, it disables some static analysis making it less careful when compiling. Please reread the chapters I linked to you because it seems like you fundamentally misunderstand what unsafe rust is. I'm happy to answer any questions you may have to clarify it.
If you have any questions, I would be happy to forward them to my ChatGPT Pro subscription, and then relay the answer back to you.
Rust is an AI native language, it's best to start there.
In 99% of cases, yes of course you’re right, factor this loop.
In this specific case? This is trivial code, that will likely _never_ change. If it does change, it’s extremely unlikely that the two loops would accidentally diverge (the dev would likely not miss one branch, tests would catch it, reviewers would catch it). So if you get any upside by keeping the two loops, it might be worth it.
Here you get 8 bytes back. I honestly can’t see how that would ever matter, but hey it’s _something_, and of course this is a very old program that was running on memory-constrained machines.
So it’s a trade-off of (minor) readability versus (minor) runtime optimisation. I think it’s the better choice (although it’s very minor).
Or maybe there’s a better reason they chose this pattern… can’t imagine the compiler would generate worse code, but maybe it did back in the days?
If you consistently deduplicate code that is supposed to do the same and evolve the same, then any duplicated code sticks out as a statement of “this isn’t the same”, and in the present case it then makes you wonder what is supposed to be different about both cases. In other words, such code casts doubt on one’s own understanding, raising the question whether one might be overlooking an important conceptual reason for why the code is being kept duplicated. So in that sense I disagree that the duplicated version is more readable, because it immediately raises unanswered questions.
About possible performance reasons, those need an explanatory comment, exactly for the above reason. And also, if performance reasons warrant complicating the code, then it isn’t “as simple as it gets” any more. I was commenting because I disagreed with that latter characterization.
> in that sense I disagree that the duplicated version is more readable
I didn't say it is, I agreed it's _less_ readable. I said it's trading off readability for 8 bytes of memory at runtime.
> If you consistently deduplicate code that is supposed to do the same and evolve the same, then [...]
I agree with all this. I'm not saying to consistently go for the deduplicated approach (I don't think anyone would say that), I'm saying it's a reasonable trade-off in this specific case (each branch is still trivial, and the code won't evolve much if at all).
> About possible performance reasons, those need an explanatory comment, exactly for the above reason.
Agreed.
> if performance reasons warrant complicating the code, then it isn’t “as simple as it gets” any more. I was commenting because I disagreed with that latter characterization.
Also agreed.
This would be terrible, I thought rust was a safe language...
for (;;) {
if (argc > 1)
puts(argv[1]);
else
puts("y");
}
?You said "it’s about duplicating logic that should inherently be the same", but that is exactly how it is more explicit, by having this duplication. I assume your problem is with the two "puts()"?
But still, I don’t see why you wouldn’t first name what you want to output before starting the outputting. If anything, I’d place the whole output loop in a separate function and have two calls to that function. Nevertheless, it’s even better to express in code the fact that the program doesn’t want to make a distinction between a literal “y” and an argument “y”, by consolidating them into the same variable.
Another way to do this would be to have a static default argument array containing the “y”, and for example having:
if (argc <= 1) { argv = default_argv; }
for (;;) { puts(argv[1]); }
This would make explicit the fact thst the argument-less invocation is merely a shortcut for an invocation with an argument and doesn’t otherwise provide any new or different behavior.Though I think the separate variable (what) is clearly preferable.