And it's always about explaining to the target person's level of understanding. A layman isn't going to know the difference between languages and why pick one vs. another. That's a long digression. Explaining why to use Rust to a Python expert is a very different discussion.
An expert can switch between explanations as required for the audience. Non-experts, in my experience, cannot tailor the explanation for the audience. They typically bottom out at a level that leaves them unable to meet the questioner in the middle.
Hell, I've been the non-expert, especially when it comes to something like why a particular material was acting like a diode instead of not passing the signal or passing the signal intact. I can regurgitate that the half-rectified signal from the aggressor is bleeding into the signal of interest, but I can't tell you why. That's when I'll tell you to talk to the EE team for specifics on why, as well as what they plan to do to fix it.
I chose this example as I assumed it would be clear and non-controversial enough to make my point, ie., I assumed most HN readers would appreciate that a person claiming Rust's memory safety model made it safter than an interpreted language would be a person clearly deeply confused about the meaning of any of these terms.
In general though, GC means automatic memory management which is effectively a kind of dynamic memory safety.
This is often more apparent (though a rampant problem nonetheless!) in policy decisions. Like how KOSA is supposed to "protect kids online" but what it mostly does as written is train people to get their identities stolen while making websites even more cumbersome than they already are. If I think it's a dumb bill, someone might say "What, you don't want kids to be safe?", as that's actually a lot of the point of calling it that
If they don't know anything specific, then it's pretty safe to say "Well, there are some differences in the languages, and you might choose one over the other for performance or ecosystem reasons, but they're both pretty safe overall. You probably don't need to worry too much about it, TBH."
You may not understand their level, and may be unable to negotiate it due to vocabular barrier (people invent non-standard vocab all the time). Your oversimplifications may bear unintended consequences, etc. You must take that into account and create a plan to make it clear.
And when you have that skill without any expertise, they call you politician. Only a politician may answer “easy” on a hard question and tell something unrelated for few paragraphs cause he doesn’t know anything on the original one.
This isn't actually bad in all cases though. It's like learning about science in primary school. You're gonna get some things simplified in a way that might be considered incorrect by those who are experts, but without some base layer of understanding to bootstrap from, you won't be able to become an expert.
on the other hand, python is more productive than rust, so if you're time-constrained, sometimes using python will get you a higher-quality product, for example because it's better tested or has a less error-prone or more forgiving user interface. both python and rust fail only at run time when they detect index errors, and users can make dangerous errors with any potentially dangerous program
on the gripping hand, rust runs enormously faster than python, and sometimes optimization trades off against testing time and ui iteration time in the same way that writing more code does, and while writing python is faster, reading it often isn't, so there may be some size of program above which python has no advantages
so i think it's better to say that the question is based on an oversimplification rather than an error. to explain this to a layman i would probably tell some stories of programmers working late nights and delivering unusable guis
Every bytecode instruction is implicitly wrapped in a lock.
Of course, you could still get semantic errors by locking the wrong things at the wrong time; but you can do that in Rust as well.
A “data race” is simultaneous access of memory from multiple threads, where at least one access is a write. It’s undefined behaviour in modern compilers (including LLVM therefore Rust).
Rust prevents that (except unsafe), as does Python.
All “semantic” concurrency bugs that can be written in Python can also be written in Rust.
another definition of a data race condition is that it's a case where different interleavings of thread accesses to shared data produce different results. see https://en.m.wikipedia.org/wiki/Race_condition for more details and background on the concept
such bugs can be written in rust with unsafe, but not without it
hmm, thinking about it more, i wonder if what i'm saying makes sense
Not to mention, Rust chose not to do anything about the memory fence problem. You're probably mostly fine on x86, but acquire/release semantics and all that nonsense still apply when writing concurrent algorithms in Rust (you'll often get lucky if you have something like a queue/channel and use message passing, since implementations of those often have a few fences internally, probably the fences you need for semantic correctness in your own algorithms). You're a lot more likely to see that sort of problem crop up in embedded work.
[0] That's obviously a bad idea, but more intricate concurrent algorithms are tricky to write in Rust for the same reason they're tricky to write in other languages. You get a bit of help from the compiler which you wouldn't really in Python if you design things to leverage the type system and prove the invariants you need to uphold, but the compiler doesn't know about any of those invariants aside from data races.
- Soundness of their semantics at a conceptual level
- Correct implementation of the semantics in rustc (in Rust)
- Correct translation of those semantics to LLVM IR targeting OS syscalls in rustc (in Rust)
- Correct translation of LLVM IR to native code in LLVM (written in C++)
- Correct implementation of OS syscalls (typically in C)
Python's safety guarantees typically depend on:
- Soundness of their semantics at a conceptual level
- Correct implementation of the semantics in CPython (in C)
- Correct translation of C to LLVM IR targeting OS syscalls in Clang (in C++)
- Correct translation of LLVM IR to native code in LLVM (written in C++)
- Correct implementation of OS syscalls (typically in C)
Both are typically contingent on correct implementation of a huge swath of C/C++ and Rust code. Even if the entire stack were written in Rust, it still wouldn't be sufficient to guarantee memory safety, since bugs anywhere in the stack could introduce memory unsafety into compiled Rust code.
Rust's guarantees come entirely at the first two layers of the stack: If the semantics are sound, and the semantics are implemented correctly in rustc, then the generated LLVM IR (treated abstractly) has memory safety. Python has similar guarantees: if its semantics are sound, and the semantics are implemented correctly in CPython compiler and interpreter, then the resulting execution of the interpreter has memory safety.
Meanwhile, the expert who got everything technically correct gets in an argument over irrelevant trivialities.
The person claiming Rust is safer than python is so whoely confused this 2min tap-dance isnt good enough.
When you're dealing with people with a-bit-more-than-surface understandings, the main problem is their head is full of misunderstandings. It is these that can take hours, or years, to undo.
To suppose otherwise is to suppose that all questions can be answered in a cute couple of setences. This is, indeed, the opposite lesson of expertise.