> You've created a logical justification for a myopic, misanthropic world view.
Nobody said it wouldn't be nice, but that it does not confer "obligation". This is the key word. I would argue a world where people do things because they want to, and not because they feel they have to, would actually generally be a nicer world to live in.
> Many find reciprocation important in a relationship.
Yes, and those sorts of relationships aren't really built on much if a gift obligates the other to repay. Why even buy lunch then? It just becomes this back and forth obligation and it is wearing and actually erodes the relationship slightly, if anything. I would argue a true gift is one that does not obligate the other party to reciprocate. That does NOT mean it would not be a decent thing to do something nice (for the other person OR someone else), but just that it is not obligated. The person should not feel a weight to do so. Once this weight is lifted, it is actually very freeing, and it strengthens the relationship, if anything.
I don't buy someone lunch with an implicit expectation that they'll buy me lunch in the future. That's tacky and gross. I buy lunch because I wanted to buy them lunch, and if they decide to buy me lunch, I happily accept.
Means you're not in the "many" segment. Doesn't mean many others are not in the "many" segment. I, myself, find reciprocation important even if not for identical "gifts".
A better route for something like Go IMO is to move to a compacting collector, this would allow them to move to a bump allocator like Java for super fast allocations and would make deallocation effectively "free" by only moving live objects. They may need to make it generational so they aren't constantly moving long lived objects, but that is a memory vs cpu trade off (could be one more GC flag?). If I recall, the previous objection was because of CGo, which would require pinning (since C wouldn't tolerate moved pointers), but every Go dev I know hates CGo and generally avoids it, plus I see they added "runtime.Pinner" in 1.21 which should solve that I suspect (albeit it would suddenly be required I expect for pointers retained in C). Is anyone aware of what other challenges there are moving to a compacting collector/bump allocator?
> this would allow them to move to a bump allocator like Java for super fast allocations and would make deallocation effectively "free" by only moving live objects
Ah, you've been misled as well. Super fast allocations is a meme. Yes, the very act of allocating is fast, great. Just like tossing trash on the floor. Super fast. Now you have a pile of garbage on the floor that you need to clean up. How fast are you going to end up being after the clean up?
In a design space as tightly constrained as a GC you can't just make something fast. You have to trade off something else to get it. So now that you have sacrificed something to make the act of allocating fast, you've also encouraged programmers using your language to allocate willy-nilly—it's fast after all. Now the pile of garbage is rising at an alarming rate and your self-gimped GC has to deal with it all.
Making allocations fast is a positive feedback loop that degrades GC performance. You want allocations to be slow and to leverage the leeway from that tradeoff to get a faster GC. Moreover, this will provide backpressure to the entire package ecosystem to limit allocations, further improving performance.
Go exposes raw pointers to the programmer, and its current GC is entirely non-moving. Even excluding cgo, I think a moving one would probably break real programs that rely on pointer values.
Yes, there's a case to be made that exposing "real" pointers in a GC'd language was a substantial mistake, but I guess it simplified _some_ parts of FFI. The trade-off so far maybe is fine, but it is a shame that there are certain things that can't be done without introducing new substantial costs. Maybe the compiler could learn to do something suuuper clever like recognize when pointers are being used non-transparently and automatically pin those, seems fraught with potential error though, trivial example being stuff like &a[0] (that ones easier to catch, others might not be).
True, I forgot about unsafe package. They would probably have to make it a Go 2 thing and add indirection to raw pointers or a need to "pin" them. Since pinning would already exist for CGo I suspect that would make more sense and wouldn't have performance penalty.
It is also equally odd to me that people want to cling so hard to C, when something like Rust (and other modern languages for that matter), have so much nicer eco systems, memory safety aside. I mean C doesn't even have a builtin hashtable or vector, let alone pattern matching, traits and sum types. I get this is about AI and vibe coding, but we aren't at a point yet where zero human interaction is reasonable, so every code base should assume some level of hybrid human/AI involvement. Why people want so badly to start a new code base in C is beyond me (and yes, I've written a lot of C in my time, and I don't hate it, but it didn't age well in expressiveness).
> It is also equally odd to me that people want to cling so hard to C, when something like Rust (and other modern languages for that matter), have so much nicer eco systems, memory safety aside.
Simplicity? I learned Rust years ago (when it was still pre release), and when i now look at a lot of codebases, i can barely get a sense what is going on, with all the new stuff that got introduced. Its like looking at something familiar and different at the same time.
I do not feel the same when i see Go code, as so little has changed / got added to it. The biggest thing is probably generics and that is so rarely used.
For me, this is, what i think, appeals for C programmers. The fact that the language does not evolve and has been static.
If we compare this to C++, that has become a mess over time, and i know i am getting downvoted for this, Rust feels like its going way too much in the Rust++ route.
Like everybody and their dog wants something added, to make Rust do more things, but at the same moment, it feels like its repeating the C++ history. I have seen the same issue with other languages that started simple, and then becomes monsters of feature sets. D comes to mind.
So when you see the codebase between developers, the different styles because of the use of different feature sets, creates this disconnect and makes it harder for people to read other code. While with C, because of the language limits, your more often down a rather easier way to read the same code. If that makes sense?
I disagree. I've been writing heavy Rust for 5 years, and there are many tasks for which what you say is true. The problem is Rust is a low level language, so there is often ceremony you have to go through, even if it doesn't give you value. Simple lifetimes aren't too bad, but between that and trait bounds on some one else traits that have 6 or 7 associated types, it can get hairy FAST. Then consider a design that would normally have self referential structs, or uses heavy async with pinning, async cancellation, etc. etc.
I do agree that OFTEN you can get good velocity, but there IS a cost to any large scale program written in Rust. I think it is worth it (at least for me, on my personal time), but I can see where a business might find differently for many types of programs.
> The problem is Rust is a low level language so there is often ceremony you have to go through, even if it doesn't give you value.
As is C++ which I compared it to, where there is even more boilerplate for similar tasks. I spent so much time working with C++ just integrating disparate build systems in languages like Make and CMake which just evaporates to nothing in Rust. And that's before I even get to writing my code.
> I do agree that OFTEN you can get good velocity, but there IS a cost to any large scale program written in Rust.
I'm not saying there's no cost. I'm saying that in my experience (about 4 years into writing decently sized Rust projects now, 20+ years with C/C++) the cost is lower than C++. C++ is one of the worst offenders in this regard, as just about any other language is easier and faster to write software in, but also less capable for odd situations like embedded, so that's not a very high bar. The magical part is that Rust seems just as capable as C++ with a somewhat lower cost than C++. I find that cost with Rust often approaches languages like Python when I can just import a library and go. But Python doesn't let me dip down to the lower level when I need to, whereas C++ and Rust do. Of the languages which let me do that, Rust is faster for me to work in, no contest.
So it seems like we agree. Rust often approaches the productivity of other languages (and I'd say surpasses some), but doesn't hide the complexity from you when you need to deal with it.
> I don't find that to be the case. It may be slower for a month or two while you learn how to work with the borrow checker, but after the adjustment period, the ideas flow just as quickly as any other language.
I was responding to "as any other language". Compared to C++, yes, I can see how iteration would faster. Compared to C#/Go/Python/etc., no, Rust is a bit slower to iterate for some things due to need to provide low level details sometimes.
> Rust is a bit slower to iterate for some things due to need to provide low level details sometimes.
Sometimes specific tasks in Rust require a little extra effort - like interacting with the file picker from WASM required me to write an async function. In embedded sometimes I need to specify an allocator or executor. Sometimes I need to wrap state that's used throughout the app in an Arc(Mutex()) or the like. But I find that there are things like that in all languages around the edges. Sometimes when I'm working in Python I have to dip into C/C++ to address an issue in a library linked by the runtime. Rust has never forced me to use a different language to get a task done.
I don't find the need to specify types to be a particular burden. If anything it speeds up my development by making it clearer throughout the code what I'm operating on. The only unsafe I've ever had to write was for interacting with a GL shader, and for binding to a C library, just the sort of thing it's meant for, and not really possible in those other languages without turning to C/C++. I've always managed to use existing datastructures or composites thereof, so that helps. But that's all you get in languages like C#/Go/Python/etc. as well.
The big change for me was just learning how to think about and structure my code around data lifetimes, and then I got the wonderful experience other folks talk about where as soon as the code compiles I'm about 95% certain it works in the way I expect it to. And the compiler helps me to get there.
I'm pretty familiar with the idiom here and I don't find error/result mapping fluent-style patterns all that easy to read or write. My experience is basically that you sort of come to understand "this goo at the end of the expression is just coercing the return value into whatever alternate goo the function signature dictates it needs", which is not at all the same thing as careful error handling.
Again: I think Rust as a language gets this right, better than Go does, but if I had to rank, it'd be (1) Rust explicit enum/match style, (2) Go's explicit noisy returns, (3) Rust terse error propagation style.
Basically, I think Rust idiom has been somewhat victimized by a culture of error golfing (and its attendant error handling crates).
> you sort of come to understand "this goo at the end of the expression is just coercing the return value into whatever alternate goo the function signature dictates it needs", which is not at all the same thing as careful error handling.
I think the problem is Rust does a great job at providing the basic mechanics of errors, but then stops a bit short.
First, I didn't realize until relatively recently that any `String` can be coerced easily into a `Box<dyn Error + Send + Sync>` (which should have a type alias in stdlib lol) using `?`, so if all you need is strings for your users, it is pretty simple to adorn or replace any error with a string before returning.
Second, Rust's incomplete error handling is why I made my crate, `uni_error`, so you can essentially take any Result/Error/Option and just add string context and be done with it. I believe `anyhow` can mostly do the same.
I do sorta like Go's error wrapping, but I think with either anyhow or my crate you are quickly back in a better situation as you gain compile time parameter checking in your error messages.
I agree Rust has over complicated error handling and I don't think `thiserror` and `anyhow` with their libraries vs applications distinction makes a lot of sense. I find my programs (typically API servers) need the the equivalent of `anyhow` + `thiserror` (hence why I wrote `uni_error` - still new and experimental, and evolving).
An example of error handling with `uni_error`:
use uni_error::*;
fn do_something() -> SimpleResult<Vec<u8>> {
std::fs::read("/tmp/nonexist")
.context("Oops... I wanted this to work!")
}
fn main() {
println!("{}", do_something().unwrap_err());
}
Right, for error handling, I'd rather have Rust's bones to build on than Go's. I prefer Go to Rust --- I would use Go in preference to Rust basically any time I could get away with it (acknowledging that I could not get away with it if I was building a browser or an LKM). But this part of Rust's type system is meaningfully better than Go's.
Which is why it's weird to me that the error handling culture of Rust seems to steer so directly towards where Go tries to get to!
Interesting. It is semi-rare that I meet someone who knows both Rust and Go and prefers Go. Is it the velocity you get from coding in it?
I have a love/hate relationship with Go. I like that it lets me code ideas very fast, but my resulting product just feels brittle. In Rust I feel like my code is rock solid (with the exception of logic, which needs as much testing as any other lang) often without even testing, just by the comfort I get from lack of nil, pattern matching, etc.
I think this is kind of a telling observation, because the advantage to working in Go over Rust is not subtle: Go has full automatic memory management and Rust doesn't. Rust is safe, like Go is, but Rust isn't as automatic. Building anything in Rust requires me to make a series of decisions that Go doesn't ask me to make. Sometimes being able to make those decisions is useful, but usually it is not.
The joke I like to snark about in these kinds of comparisons is that I actually like computer science, and I like to be able to lay out a tree structure when it makes sense to do so, without consulting a very large book premised on how hard it is to write a doubly-linked list in Rust. The fun thing is landing that snark and seeing people respond "well, you shouldn't be freelancing your own mutable tree structures, it should be hard to work with trees", from people who apparently have no conception of a tree walk other than as a keyed lookup table implementation.
But, like, there are compensating niceties to writing things like compilers in Rust! Enums and match are really nice there too. Not so nice that I'd give up automated memory management to get them. But nice!
I'm an ex-C++/C programmer (I dropped out of C++ around the time Alexandrescu style was coming into vogue), if my background helps any.
> Go has full automatic memory management and Rust doesn't
It doesn't? In Go, I allocate (new/make or implicit), never free. In Rust, I allocate (Box/Arc/Rc/String), never free. I'm not sure I see the difference (other than allocation is always more explicit in Rust, but I don't see that as a downside). Or are you just talking about how Go is 100% implicit on stack vs heap allocation?
> Sometimes being able to make those decisions is useful, but usually it is not.
Rust makes you think about ownership. I generally like the "feeling" this gives me, but I will agree it is often not necessary and "just works" in GC langs.
> I actually like computer science, and I like to be able to lay out a tree structure when it makes sense to do so, without consulting a very large book premised on how hard it is to write a doubly-linked list in Rust. The fun thing is landing that snark and seeing people respond "well, you shouldn't be freelancing your own mutable tree structures, it should be hard to work with trees", from people who apparently have no conception of a tree walk other than as a keyed lookup table implementation.
I LOVE computer science. I do trees quite often, and they aren't difficult to do in Rust, even doubly linked, but you just have to use indirection. I don't get why everyone thinks they need to do them with pointers, you don't.
Compared to something like Java/C# or anything with a bump allocator this would actually be slower, as Rust uses malloc/free, but Go suffers from the same achilles heel here (see any tree benchmark). In Rust, I might reach for Bumpalo to build the tree in a single allocation (an arena crate), but only if I needed that last ounce of speed.
If you need to edit your tree, you would also want the nodes wrapped in a `RefCell`.
You could have done that in Rust but you wouldn't, because the allure of just typing a single character of
?
is too strong.
The UX is terrible — the path of least resistance is that of laziness. You should be forced to provide an error message, i.e.
?("failed to create file: {e}")
should be the only valid form.
In Go, for one reason or another, it's standard to provide error context; it's not typical at all to just return a bare `err` — it's frowned upon and unidiomatic.
> I would assume trivial means the default approach works for most cases. Perhaps mutable global variables are not a common use case. Unsafe might make it easier, but it’s not obvious and probably undesired.
I'm a Rust fan, and I would generally agree with this. It isn't difficult, but trivial isn't quite right either. And no, global vars aren't terribly common in Rust, and when used, are typically done via LazyLock to prevent data races on intialization.
> I don’t know Rust, but I’ve heard pockets of unsafe code in a code base can make it hard to trust in Rust’s guarantees. The compromise feels like the language didn’t actually solve anything.
Not true at all. First, if you aren't writing device drivers/kernels or something very low level there is a high probability your program will have zero unsafe usages in it. Even if you do, you now have an effective comment that tells you where to look if you ever get suspicious behavior. The typical Rust paradigm is to let low level crates (libraries) do the unsafe stuff for you, test it thoroughly (Miri, fuzzing, etc.), and then the community builds on these crates with their safe programs. In contrast, C/C++ programs have every statement in an "unsafe block". In Rust, you know where UB can or cannot happen.
> Even if you do, you now have an effective comment that tells you where to look if you ever get suspicious behavior.
By the time suspicious behavior happens, isn’t it kind of a critical inflection point?
For example, the news about react and next that came out. Once the code is deployed, re-deploying (especially with a systems language that quite possibly lives on an air-gapped system with a lot of rigor about updates) means you might as well have used C, the dollar cost is the same.
Are you with a straight face saying that occasionally having a safety bug in limited unsafe areas of Rust is functionally the same as having written the entire program in an unsafe language like C?
One, the dollar cost is not the same. The baseline floor of quality will be higher for a Rust program vs. a C program given equal development effort.
Second, the total possible footprint of entire classes of bugs is zero thanks to design features of Rust (the borrowck, sum types, data race prevention), except in a specifically delineated areas which often total zero in the vast majority of Rust programs.
> The baseline floor of quality will be higher for a Rust program vs. a C program given equal development effort.
Hmm, according to whom, exactly?
> Second, the total possible footprint of entire classes of bugs is zero thanks to design features of Rust (the borrowck, sum types, data race prevention), except in a specifically delineated areas which often total zero in the vast majority of Rust programs.
And yet somehow the internet went down because of a program written in rust that didn’t validate input.
> And yet somehow the internet went down because of a program written in rust that didn’t validate input.
You're ignoring other factors (it wasn't just Cloudflare's rust code that led to the issue), but even setting that aside your framing is not accurate. The rust program went down because the programmer made a choice that, given invalid input, it should crash. This could happen in every language ever made. It has nothing to do with rust.
> This could happen in every language ever made. It has nothing to do with rust.
Except it does. This also has to do with culture. In Rust, I get the impression that one can set it up as roughly two communities.
The first does not consider safety, security and correctness to be the responsibility of the language, instead they consider it their own responsibility. They merely appreciate it when the language helps with all that, and take precautions when the language hinders that. They try to be honest with themselves.
The second community is careless, might make various unfounded claims and actions that sometimes border on cultish and gang mob behavior and beliefs, and can for instance spew unwrap() all over codebases even when not appropriate for that kind of project, or claim that a Rust project is memory safe even when unsafe Rust is used all over the place with lots of basic bugs and UB-inducing bugs in it.
The second community is surprisingly large, and is severely detrimental to security, safety and correctness.
Again, this has nothing to do with the point at hand, which is that "in any language, a developer can choose the crash the problem if a unrecoverable state happens". That's it.
Tell me about how these supposed magical groups have anything at all to do with language features. What language can magically conjure triple the memory from thin air because the upstream query returned 200+ entries instead of the 60-ish you're required to support?
I don't think you're actually disagreeing with the person you're responding to here. Even if you take your grouping as factual, there's nothing that limits said grouping to Rust programmers. Or in other words:
> This could happen in every language ever made. It has nothing to do with rust.
> And yet somehow the internet went down because of a program written in rust that didn’t validate input.
What? The Cloudflare bug was from a broken system configuration that eventually cascaded into (among other things) a Rust program with hardcoded limits that crashed loudly. In no way did that Rust program bring down the internet; it was the canary, not the gas leak. Anybody trying to blame Rust for that event has no idea what they're talking about.
> And yet somehow the internet went down because of a program written in rust that didn’t validate input.
Tell me which magic language creates programs free of errors? It would have been better had it crashed and compromised memory integrity instead of an orderly panic due to an invariant the coder didn't anticipate? Type systems and memory safety are nice and highly valuable, but we all know as computer scientists we have yet to solve for logic errors.
> And yet somehow the internet went down because of a program written in rust that didn’t validate input.
No, it _did validate_ the input, and since that was invalid it resulted in an error.
People can yap about that unwrap all they want, but if the code just returned an error to the caller with `?` it would have resulted in a HTTP 500 error anyway.
> So it validated in the input and failed in an unsafe way. Is that what you’re saying? Instead of rejecting the input and failing in a safe way.
It rejected the input and "failed" in a loud way (showing an error) for the user, as opposed to not rejecting the invalid input and continuing anyway in a degraded/invalid state, which would instead have allowed users to continue browsing but would not have worked properly for some other purposes (e.g. it probably would not have continued blocking malicious/bad scraper requests). Neither is ideal, though of course depending on your priorities one might be better than the other.
> My only point was, the language doesn’t matter. It could have been written in brainfuck.
Yeah I definitely agree. My point was that the error was also somewhere else, since an internally-controlled input was invalid.
> might as well have used C, the dollar cost is the same.
When your unsafe area is small, you put a LOT of thought/testing into those small blocks. You write SAFETY comments explaining WHY it is safe (as you start with the assumption there will be dragons there). You get lots of eyeballs on them, you use automated tools like miri to test them. So no, not even in the same stratosphere as "might as well have used C". Your probability of success vastly higher. A good Rust programmer uses unsafe judiciously, where as a C programmer barely blinks as they need ensure every single snippet of their code is safe, which in a large program, is an impossible task.
As an aside, having written a lot of C, the ecosystem and modern constructs available in Rust make writing large scale programs much easier, and that isn't even considering the memory safety aspect I discuss above.
SAFETY comments do not magically make unsafe Rust correct nor safe. And Miri cannot catch everything, and is magnitudes slower than regular program running.
I think you might be misreading GP's comment. They are not claiming that SAFETY comments and MIRI guarantee correctness/safety; those are just being used as examples of the extra effort that can be and are expended on the relatively few unsafe blocks in your codebase, resulting in "your probability of success [being] vastly higher" compared to "might as well have used C".
> First, if you aren't writing device drivers/kernels or something very low level there is a high probability your program will have zero unsafe usages in it.
from the original comment. Meanwhile all C code is implicitly “unsafe”. Rust at least makes it explicit!
But even if you ignore memory safety issues bypassed by unsafe, Rust forces you to handle errors, it doesn’t let you blow up on null pointers with no compiler protection, it allows you to represent your data exhaustively with sum types, etc etc etc
Because writing proper kernel C code requires decades of experience to navigate the implicit conventions and pitfalls of the existing codebase. The human pipeline producing these engineers is drying up because nobody's interested in learning that stuff by going through years of patch rejection from maintainers that have been at it since the beginning.
Rust's rigid type system, compiler checks and insistence on explicitness forces a _culture change_ in the organization. In time, this means that normal developers will regain a chance to contribute to the kernel with much less chance of breaking stuff. Rust not only makes compiled binary more robust but also makes the codebase more accessible.
I am quite certain that someone who has been on HN as long as you have is capable of understanding the difference between 0% compiler-enforced memory safety in a language with very weak type safety guarantees and 95%+ of code regions even in the worst case of low-level driver code that performs DMA with strong type safety guarantees.
The first two is the same article, but they point out that certain structures can be very hard to write in rust, with linked lists being a famous example. The point stands, but I would say the tradeoff is worth it (the author also mentions at the end that they still think rust is great).
The third link is absolutely nuts. Why would you want to initialize a struct like that in Rust? It's like saying a functional programming language is hard because you can't do goto. The author sets themselves a challenge to do something that absolutely goes against how rust works, and then complains how hard it is.
If you want to do it to interface with non-rust code, writing a C-style string to some memory is easier.
And it can easily be more than 5%, since some projects both have lots of large unsafe blocks, and also the presence of an unsafe block can require validation of much more than the block itself. It is terrible of you and overall if my understanding is far better than yours.
And even your argument taken at face value is poor, since if it is much harder, and it is some of the most critical code and already-hard code, like some complex algorithm, it could by itself be worse overall. And Rust specifically have developers use unsafe for some algorithm implementations, for flexibility and performance.
> since if it is much harder, and it is some of the most critical code and already-hard code, like some complex algorithm, it could by itself be worse overall.
(Emphasis added)
But is it worse overall?
It's easy to speculate that some hypothetical scenario could be true. Of course, such speculation on its own provides no reason for anyone to believe it is true. Are you able to provide evidence to back up your speculation?
Is three random people saying unsafe Rust is hard supposed to make us forget about C’s legendary problems with UB, nil pointers, memory management bugs, and staggering number of CVEs?
You have zero sense of perspective. Even if we accept the premise that unsafe Rust is harder than C (which frankly is ludicrous on the face of it) we’re talking about a tiny fraction of the overall code of Rust programs in the wild. You have to pay careful attention to C’s issues virtually every single line of code.
With all due respect this may be the singular dumbest argument I’ve ever had the displeasure of participating in on Hacker News.
> Even if we accept the premise that unsafe Rust is harder than C (which frankly is ludicrous on the face of it)
I think there's a very strong dependence on exactly what kind of unsafe code you're dealing with. On one hand, you can have relatively straightforwards stuff like get_unsafe or calling into simpler FFI functions. On the other hand, you have stuff like exposing a safe, ergonomic, and sound APIs for self-referential structures, which is definitely an area of active experimentation.
Of course, in this context all that is basically a nitpick; nothing about your comment hinges on the parenthetical.
Well, you're the one asking for a comparison with C, and this subthread is generally comparing against C, so you tell us.
> Modern C++ provides a lot of features that makes this topic easier, also when programs scale up in size, similar to Rust. Yet without requirements like no universal aliasing. And that despite all the issues of C++.
Well yes, the latter is the tradeoff for the former. Nothing surprising there.
Unfortunately even modern C++ doesn't have good solutions for the hardest problems Rust tackles (yet?), but some improvement is certainly more welcome than no improvement.
> Which is wrong
Is it? Would you be able to show evidence to prove such a claim?
> For faster startup, lower memory footprint and so on
Any idea how they do this? My WSL2 starts insanely fast, like about 1-2 seconds. I've never seen a linux distro natively boot that fast. Assuming they suppress any sort of BIOS startup screen for starters, but what else?
It’s a very trimmed down kernel with minimal set of drivers and modules. It doesn’t even support SD cards out of the box. That’s probably the main reason as no hardware probing/initialization delays are incurred.
At high level, WSL2 provides a single optimized VM and Microsoft-compiled Linux kernel. Optimized here means that the VM only provides a small set of devices to the Linux kernel, and the kernel operates with exact known hardware, which is much smaller and simpler compared to a full blown kernel (which detects a large variety of hardware) and fuller featured VMs (c.f. qemu emulated devices: https://kashyapc.fedorapeople.org/virt/qemu/qemu-list-of-emu...).
And when you run multiple "distributions" or instances, they all share the same running VM and kernel. So after a one-time startup of the VM+kernel, opening more distributions/instances is like starting new system containers (similar to lxc/lxd or systemd-nspawn, which are also very quick to spawn on Linux) rather than new VMs. The architecture is quite similar to Linux-on-ChromeOS (Crostini).
Actually I don't know it either. But WSL2 doesn't really start a lot of processes, like a desktop/server Linux distribution. It starts up only a minimal set of processes, and a shell.
dmesg looks like the kernel is booting up normally, so I guess they don't use some memory snapshots magic.
I guess they just tweaked the kernel and the hypervisor to start up fast. There is also no BIOS/UEFI delay.
Nobody said it wouldn't be nice, but that it does not confer "obligation". This is the key word. I would argue a world where people do things because they want to, and not because they feel they have to, would actually generally be a nicer world to live in.
> Many find reciprocation important in a relationship.
Yes, and those sorts of relationships aren't really built on much if a gift obligates the other to repay. Why even buy lunch then? It just becomes this back and forth obligation and it is wearing and actually erodes the relationship slightly, if anything. I would argue a true gift is one that does not obligate the other party to reciprocate. That does NOT mean it would not be a decent thing to do something nice (for the other person OR someone else), but just that it is not obligated. The person should not feel a weight to do so. Once this weight is lifted, it is actually very freeing, and it strengthens the relationship, if anything.
reply