I appreciate that his anger is still there, its just worded differently, in a more modern (softer) attack. Is this still how we control developers in 2025? Yes! Deal with it or go fork it yourself. The day this goes away is the day Linux begins to die a death of 1,000,000 cuts in code quality.
To me (a Greek), what he says is fine. He never gets personal, he talks about the arguments/points/issues, not the person. "complete garbage arguments" is a judgement of the arguments, not of the person, and it's fine to tell someone their arguments are garbage, if that's what you think about them.
Americans/Canadians/the English will interpret that as anger, but, in other cultures, it's just voicing one's opinion.
> Key, I'm f*cking tired of the fact that you don't fix problems in the code *you* write, so that the kernel then has to work around the problems you cause.
... this is getting personal, this is being knowingly crass, this is universally offensive (albeit fairly mild), and I have extremely serious doubts that in Greek being told that people are fucking tired of your behavior is "just voicing one's opinion".
You also have to appreciate that this is from an email. You don't type out an email like this and hit send without being really quite content with it. I cannot personally imagine sending an email (or even a text message) like this to anyone at work, for example, and there have been times where they definitely would have deserved this and then some.
There are communities and workplaces where this type of communication is the norm, yes, and it used to be especially common in the past (and from what I know, still often is in blue collar jobs). This is true both in and outside of America.
I'm not from America, I'm from Central-Europe. I know what being "direct and upfront" is like, and this is not that. This is just being a twat. Language like this is never productive or acceptable in any culture, and it's not some American mind-virus spreading around the world that made people figure they can and should afford to have standards regarding their interactions with one another.
If anything, the trendy bit here is the opposite, where people seem to make a sport out of mischaracterizing being crass as saying hard truths. Just like how cynicism is often mistaken as intellectualism, this is also utterly misguided, and Linus is being washed of his personal faults out of respect, not because he's not at fault in reality.
The best of both worlds for me is when I can naturally just mingle with others without this issue cropping up, because the chemistry just works out on its own. I miss and greatly cherish those people I've met over the years who I was able to collaborate and spend time with like that. Instead of subscribing to either extreme, that's the kind of interaction I'm actually wishing to experience more of.
Regrettably, I feel this has been becoming less and less likely over time, which I attribute to the growing distrust and hostility among people at large, as well as the countless other (what I perceive as) dysfunctional social dynamics on the internet these days (e.g. mainstream political activism and counteractivism on community spaces of all kinds). And then who knows.
I'd wager that a lot of people here are probably fine with someone shouting "motherfucker" at a problem in your screen, or saying that something is "fucking stupid", but draw the line at shouting or telling this to a person... especially in a public email, and even more especially when you're in a position of power over them.
In fact I do happen to land in traps in Germany and UK, where when being more frontal at work turns bad, because apparently we have to be all smiles, and complain in a positive way with euphemisms.
A technique that I have improved over the years, talk back with the feeback level expected from the target culture, when I know their background beforehand.
Sure, he could have omitted the word "fucking" there, which doesn't add much, but "I'm tired of the fact that you don't fix the problems in your code" is really good, direct, honest feedback.
I understand that the person receiving it might feel bad, but they might also feel bad with "I've noticed that sometimes you tend to leave some bugs unfixed, even if perhaps they were caused by your own commits". When you give feedback, you should steer away from making personal judgements, focus on the facts, and deliver the feedback calmly, and Linus' sentence hits two of the three, which isn't too bad.
Anglo cultures really do tend to walk on eggshells to avoid hurting feelings, which other cultures might find tiring and somewhat disingenuous.
I disagree. I don't see why Linus being tired or not is technically relevant at all. Leading with it makes it sound like he's looking for the guy to stop tiring him, rather than actually remediate his lapses in self-review.
Being courteous is not about avoiding a negative experience at all costs, it's about being considerate of it, keeping in mind that it exists. If you know you're going to tell the guy they're causing issues, then not making that about how fucking tired that makes you feel shows that you're not trying to mess with their head, but trying to actually address the issue. It's specifically to avoid the ambiguity on whether he has a problem with the person or what they're doing, since when insulted, people tend to reasonably assume they're being found to be problematic.
I really don't think this is all that culture specific, and that this is just some freak cultural mismatch having been ongoing for decades. Not ethnic cultural at least.
Tbh I agree that your citation of Linus' email was an example of not exactly productive conversation. But preventing such emotion ventillation takes effort, same as not feeling insulted when your work is criticized. And who should put in the emotional effort is imo at least partially influenced by cultural expectations.
If wanting others to not say things like how they're "fucking tired of someone else or their behavior" is making them walk on eggshells, and can remain elusive to them for decades out of cultural differences, then clearly I'm taking crazy pills, because that's just about the most outlandish proposal I've ever come across.
Kinda relevant: https://www.nytimes.com/2024/05/14/magazine/native-language-...:
> My own introduction to speaking French as an adult was less joyous. After reaching out to sources for a different article for this magazine with little success, I showed the unanswered emails to a friend. She gently informed me that I had been yelling at everyone I hoped to interview.
> Compared with English, French is slower, more formal, less direct. The language requires a kind of politeness that, translated literally, sounds subservient, even passive-aggressive. I started collecting the stock phrases that I needed to indicate polite interaction. “I would entreat you, dear Madam ...” “Please accept, dear sir, the assurances of my highest esteem.” It had always seemed that French made my face more drawn and serious, as if all my energy were concentrated into the precision of certain vowels. English forced my lips to widen into a smile.
That's a huge sacrifice when speaking of him, which we must appreciate. But to be honest, I must agree with his point of view.
Golden rule when developing projects is to stick to one (the least amount possible of) technology, otherwise, you'll end up with software for which you need to hire developers of different languages or accept the developers that won't be experts in some of them. I am working on a project that, up until a year ago, had been partly written in Scala. All the Java developers who didn't know Scala were doomed to either learn it in pain (on errors and mistakes) or just ignore tasks regarding that part of the system.
Multiple years later, what was the state of things? We had a portion of the codebase in Kotlin with dedicated native/Kotlin developers, and a portion of the codebase in RN with dedicated RN/JS developers.
Any time there's a bug it's a constant shuffle between the teams of who owns it, which part of the code, native or JS the bug is coming from, who's responsible for it. A lot of time time nobody even knows because each team is only familiar with part of the app now.
The teams silo themselves apart. Each team tries its best to hold on to the codebase - native teams tries to prevent JS team from making the whole thing JS, the JS team tries to covert as much to JS as possible. Native team argues why JS features aren't good, JS team argues the benefits over writing in native. Constant back and forth.
Now, no team has a holistic view of how the app works. There's massive chunks of the app that some other team owns and maintains in some other language. The ability to have developers "own" the app, know how it works, have a holistic understanding of the whole product, rapidly drops.
Every time there's a new feature there's an argument about whether it should be native or RN. Native team points out performance and look-and-feel concerns, RN team points out code sharing / rapid development benefits. Constant back and forth. Usually whoever has the most persuasive managers wins, rather than on technical merit.
Did we end up with a better app with our new setup, compared to one app, written in one language, with a team of developers that develop and own and know the entire app? No, no I don't think so.
Feels like pretty parallel of a situation compared to Rust/C there.
In my current job, also at FAANG, my team (albeit SRE team, not dev team), owns moderately sized codebases in C++, Go, Python and a small amount of Java. There are people “specialised” in each language, but also everyone is generally competent enough to at least read and vaguely understand code in other languages.
Now of course sometimes the issue is in the special semantics of the language and you need someone specialised to deal with it, but there’s also a large percentage which is logic problems that anyone should be able to spot, or minor changes which anyone can make.
The key problem in the situation you described seems to be the dysfunction in the teams about arguing for THEIR side, vs viewing the choice of language as any other technical decision that should be made with the bigger picture in mind. I think this partly stems from unclear leadership of how to evaluate the decision. Ideally you’d have guidance on which to prioritise between rapid development and consistency to guide your decisions and make your language choice based on that.
As your codebase scales beyond a certain point, siloing is pretty inevitable and it is better to focus on building a tree of systems and who is responsible for what. However that doesn’t absolve especially the leads from ONLY caring about their own system. Someone needs to understand things approximately to at least isolate problems between various connected systems, even if they don’t specialise in all of them.
Was this at Meta? I doubt the iOS FB app and Insta are using RN so that must leave FB messenger?
https://reactnative.dev/blog/2017/08/07/react-native-perform...
> React Native is used in multiple places across multiple apps in the Facebook family including a top level tab in the main Facebook apps. Our focus for this post is a highly visible product, Marketplace.
The Linux kernel's first "release" was in 1991, hit 1.0 in 1994, and arguably the first modern-ish release in 2004 with the 2.6 kernel. Rust's stable 1.0 release was in 2015, 13 years ago. There are people in the workforce now who were in middle school when Rust was first released. Since then, it has seen 85 minor releases and three follow-on editions, and built both a community of developers and gotten institutional buy-in from large orgs in business-critical code.
Even if you take the 1991 date as the actual first release, Rust as a stable language has existed for over 1/3 of Linux's public development history (and of course had a number of years of development prior to that). In that framing, I think that it's a little unfair to include it in the "hip new thing" box.
Even many backend devs seem to shy away from things like SQL because they're not too comfortable with it. Which isn't bad per se, it's very easy to make a small mistake in a query that crushes the database, just a personal observation of mine.
The idea that there is some rule that you don’t mix languages seems like absolute nonsense. If someone suggested to me that it was _possible_ I’d be extremely curious what wild tradeoffs they were making to get there.
However, in my work I've seen plenty of developers with all manner of interests and experiences align only on one or two languages, and if that's your company's talent pool, single language code bases seem like a good idea.
Of course this skips over all the usage of scripting languages (makefile/bash/Python/XML) which in my experience are seen as quirks of build tooling rather than part of the product.
Considering that they'll want to use Node even to make coffee, I'd argue that statement is wildly inaccurate.
The modern web is a gigantic mess with security features hacked on top of everything to make it even remotely secure and the moment it hit the desktop thanks to electron we had cross site scripting attacks that allowed everyone to read local files from a plugin description page. If anything it is the ultimate proof how bad things can go.
I have used around 20+ in my little project (mostly solo) and I have now:
* Rust
* Kotlin
* Swift
* Html
* Sql with variations for: Postgres, Sqlite, Sql Server, Firebird, DBISAM, MySql
* Go
* FreePascal
And now is when I have less languages.
People are flexible.
I have worked on lots of cross language codebases. While it’s extremely useful to have experts in language or part, one can meaningfully contribute to parts written in other languages without being an expert. Certainly programmers on the level of kernel developers should readily be able to learn the basics of Rust.
There’s lots of use cases for shared business logic or rendering code with platform specific wrapper code, e.g. a C++ or Rust core with Swift, Kotlin, and TypeScript wrappers. Lots of high level languages have a low level API for fast implementations, like CPython, Ruby FFI, etc. The other way around lots of native code engines have scripting APIs for Lua, Python, etc.
If our testing framework is in Python; writing a wrapper to code tests for your feature in Perl because you're more comfortable with it is the Wrong way to do it imo.
But if writing a FluentD plugin in Ruby solves a significant problem in the same infra; the additional language could be worth it.
Everything is about tradeoffs.
Anyway, I’m a bit of a Rust fanboy, and would generally argue that its use in kernel and other low-level applications is only a net benefit for everyone, and doesn’t add much complexity compared to the rest of these projects. But I could also see a 2030 version of C adding a borrow checker and more comparable macro features, and Rust just kind of disappearing from the scene over time, and its use in legacy C projects being something developers have to undo over time.
Something like a borrow checker can be added (and there are people on the C committee willing to see it). However, Rust's "shared xor mutable" rules are probably too strong for C, so you'd need to find some weaker model that solves a good deal of memory safety issues (maybe expressing pointer ownership and some form of invalidation is sufficient, but this is just some spitballing by me). The focus by the interested people right now is mostly around bounds-checking rather than a borrow checker.
C++ does have generics already (well templates, but you know) and so it'd be an easier lift there, but it's still a lot of work. https://safecpp.org/draft.html explains how this would be possible.
As I understand it, doing it while maintaining compatibility with old code is not possible. You'd have to add new required syntax for annotations and such.
And it's not like pointers are a rare occurrence in C. This mechanism is used pretty much everywhere: accessing array values, parameter pass-by-reference, function output parameters, string manipulation. There's no concept of function purity either, so no way to guarantee in the function definition that a function cannot outstep its bounds. Sure, there are certain safe coding conventions and rules about what you can or cannot do in a C program, but fundamentally proving that a certain memory location is only accessed through a certain variable is only possible by just running the program exhaustively -- or by confining yourself to a subset of C.
But when you only allow a subset of C, it's no longer "C with a borrow checker", especially given the ubiquitous use of pointers for standard language features. It quickly becomes "we hobbled C because we need more guarantees". To take a quote from the D manual [0], to guarantee memory safety you need to disallow:
- Casts that break the type system.
- Modification of pointer values.
- Taking the address of a local variable or function parameter.
[0] https://dlang.org/spec/memory-safe-d.htmlAdditionally, C does actually have aliasing rules, but many projects, including the kernel, turn them off. Linus in particular does not think they're worthwhile.
These rules are different than Rust's, Rust also rejected these particular rules.
> To take a quote from the D manual [0], to guarantee memory safety you need to disallow
Just to be clear, this is the list for D, not in general. Rust is fine with you taking the address of a local variable or function parameter.
If you're referring to e.g. gcc's -f[no-]strict-aliasing option, then that's more about type compatibility than about limiting the scope of memory aliasing in general. If you mean something else, I'm interested to hear more.
> this is the list for D, not in general
Yes, I know. But it's the first authoritative source I could think of on memory safety in C-like languages. I don't think the list is wrong for C proper, just probably not exhaustive.
> Rust is fine with you taking the address of a local variable
Yes! But circling back to the earlier point: in Rust you can do this specifically because the language has well-defined lifetime semantics on variables and ownership. And as such, Rust can guarantee that a) a pointer to a memory location does not outlive the scope of the memory allocation itself, and b) when two variables/pointers refer to the same memory location, there is a compiler-enforced protocol for accessing and mutating that memory.
It's about limiting the ability of pointers to alias. The C standard even has this parenthetical:
> The intent of this list is to specify those circumstances in which an object can or cannot be aliased.
You are correct that it's a pretty narrow set of rules. There are only six items on that list. But it's still an aliasing rule.