5 ms·
This is all well and good, but "zero cost abstractions" implies, well, that you're crawling _up_ the abstraction pyramid, not lost in twisty little side passage
by zephen 10mo ago
This is all well and good, but "zero cost abstractions" implies, well, that you're crawling _up_ the abstraction pyramid, not lost in twisty little side passages.
- cardiffspaceman 10mo agoTo me it implies abstraction such as a constructor, but with no overhead compared to the same steps done in some other way.
- zephen 10mo agoSure, but languages and the problems we solve with them are both multifaceted, so simply pointing to one tool and saying "this is better than the one you have in your toolbox" is fine, but the plural in "zero cost abstractions" kind of implies that most or all the tools are at parity or better.
- saghm 10mo agoIt sounds like you're saying that you consider seeing this single instance of someone writing a library with a costly abstraction to be indicative of the entire language ecosystem not fitting the paradigm. This is kind of hard to take seriously; it's not like C++ doesn't have some costly abstractions as well way more embedded into the language itself (e.g. exceptions).
- zephen 10mo ago> someone writing a library with a costly abstraction That's not what happened here. > it's not like C++ doesn't have some costly abstractions This is simultaneously both completely orthogonal to my observation that the Rust FFI is borked, and a great example of a problem that wouldn't happen in C++, because in C++ you could completely ignore the costly abstractions if necessary.
- saghm 10mo ago> > someone writing a library with a costly abstraction > That's not what happened here. Yes it is. Where do you think the `FFISafe` type that they used came from? It's not anything inherent to how Rust does FFI; it's a type someone wrote in an attempt to try to provide an abstraction, and that abstraction happened to have a cost. There's absolutely no reason anyone has to use it in order to do FFI in Rust.
- zephen 10mo agoThe extra time was being taken up in the identical assembly language function. Fixing it took wizardry.
- saghm 10mo agoThe time was taken by the code around the assembly language. It was an abstraction someone wrote in a way that happened not to be efficient. The ability of someone to write a costly abstraction doesn't take away from Rust any more than the possibility of doing that in C++ would from whether C++ has them.
- Dylan16807 10mo agoIt was caused by the code around it, but the actual CPU cycles stalled out in the assembly language, making it much harder to find the problem. Is how I understood the post. Anyway there's noting wrong with rust FFI. The overhead was because this function wanted to support two options and didn't implement that in the best way.
- Aurornis 10mo ago> That's not what happened here. Yes, it's what happened here. The article is about debugging the author's own abstraction types that had some incorrect assumptions. You do not need these wrapper types to call C functions. If the author had removed the complex extractions and called the extern "C" function directly (as is standard in Rust) there would not be the additional overhead.
- saghm 10mo agoI've never understood that to mean that every possible abstraction would be zero cost, but that the language itself provides abstractions that are zero cost. I'm not sure how you could avoid having external libraries ever implement an abstraction with a cost. I honestly can't tell from this article alone what library the type `FFISafe` is from, but it's not from std. (As an side someone whose spent a lot of time in the ecosystem might be able to infer this is likely a third-party library just from the fact that the capitalization is not in the typical format that official things use; if it were in std, I'd expect it to be FfiSafe, similar to how IoSlice[1], Arc[2], Shl[3], TypeId[4] etc. don't treat separate parts of an abbreviation/acronym/initialism as word breaks). [1]: https://doc.rust-lang.org/std/io/struct.IoSlice.html https://doc.rust-lang.org/std/io/struct.IoSlice.html [2]: https://doc.rust-lang.org/std/sync/struct.Arc.html https://doc.rust-lang.org/std/sync/struct.Arc.html [3]: https://doc.rust-lang.org/std/ops/trait.Shl.html https://doc.rust-lang.org/std/ops/trait.Shl.html [4]: https://doc.rust-lang.org/std/any/struct.TypeId.html https://doc.rust-lang.org/std/any/struct.TypeId.html
- zephen 10mo ago> I've never understood that to mean that every possible abstraction would be zero cost, but that the language itself provides abstractions that are zero cost. To me, "zero cost abstractions" means that you should use the language, because even the fancy abstractions it provides are free. Which presupposes that the language designers _believe_ that abstractions _and_ performance are both _important_. Judging by all the puff pieces on the language, I don't think I'm alone in this belief of what the average Rustacean holds to be true. > I'm not sure how you could avoid having external libraries ever implement an abstraction with a cost. But the point is that the exact same external library code has a _lower_ cost if called from the non-abstract horror of a language C, and the (partial) fix for that is really ugly looking low-level Rust crap that that took a _long_ time to figure out and is the exact opposite of an abstraction, and the full fix is not even known yet. Yes, we all know that abstractions sometimes obscure what is really going on, but the tradeoff is that the code is shorter and prettier, and easier to understand at a higher level. That's... not what is going on here.
- 10mo ago
- Aurornis 10mo ago> but "zero cost abstractions" implies, well, that you're crawling _up_ the abstraction pyramid, not lost in twisty little side passages The zero cost refers to the runtime cost, not the programming complexity.
- kelseyfrog 10mo agoWhat's a language with zero complexity-cost abstractions?
- eptcyka 10mo agoNatural language. It's a language interpreted by LLMs. It is really high level.
- bigstrat2003 10mo agoEven that has lots and lots of abstractions which add complexity. For example, figures of speech such as "shooting fish in a barrel".
- saghm 10mo agoIf anything, the fact that it's hard to come up with an example of a language like this is even more evidence that this probably isn't what anyone has ever meant by that term.
- cyco130 10mo agoNatural languages are much more complex. Complex for humans: I can learn a new programming language in an afternoon and be reasonably productive in it within a week or two. I wish I could say the same for natural languages. Complex for computers: We’ve had good compilers since the 50s. Satisfactory language models are less than five years old.
- pizza234 10mo ago"Zero cost abstractions" refers to some features of the language that provide functionalities with no runtime cost, e.g. (safe) iterators, not to a presumed simplicity of the whole language. Therefore, this is not mutually exclusive with the fact that certain concepts in Rust require more complexity than their counterpart in other languages (after all, the complexities of the borrow checker don't exist in C). In general, and it applies to the referenced article, programming with a high level of control over the implementation is complex, and there's no way around it. This article explains the concept: https://matklad.github.io/2023/01/26/rusts-ugly-syntax.html https://matklad.github.io/2023/01/26/rusts-ugly-syntax.html.
- zephen 10mo ago> "Zero cost abstractions" refers to some features of the language that provide functionalities with no runtime cost... In that case, all languages provide zero cost abstractions. > programming with a high level of control over the implementation is complex, > (after all, the complexities of the borrow checker don't exist in C). The point of an abstraction is to _hide_ complexity. > This article explains the concept The article is only half-right. People complain both about the semantics and the syntax, because Rust's implementation of both presents (in some cases) a huge cognitive load that simply doesn't exist in other languages.
- vlovich123 10mo agoFrom this thread it's pretty clear: 1. You've come up with your own unique definition of "zero cost" which isn't what the term means, at least as popularized by C++ where the concept of "zero cost abstractions" comes from. It means zero runtime cost, not zero cognitive cost. 2. Rust generally has more "zero cost abstractions" than C++ in terms of shifting traditional runtime checks into compile-time checks (e.g. while unique_ptr exists in Rust as Box, it's far more rarely used because ownership is easier to transfer). 3. Rust generally has faster defaults in the standard library so the abstractions are lower-cost than equivalents in C++ (e.g. C++ took forever to add a hash table via unordered_map and then proceeded to really fuck up the definition to inhibit high performance designs despite this being raised during standardization & haven't since revisited the issue). 4. Rust offers far more opportunities for "zero cost abstractions" than C++. Notably it's ownership rules prevent aliasing which allows the compiler to do more aggressive optimizations that can't generally be done in C++. It provides abstractions like NonNullPointer and NonZero so that unused bit patterns can be leveraged for enums (e.g. Option<NonNullPointer> is the size of a raw pointer but in C++ it's harder to pull off). Functional style and iterators are implemented to be aggressively inlined and overheads like bounds checking elided by the compiler, whereas C++ can't elide as easily and various bounds checks have to be inserted. Could go on and on. Anyway, Rust as the base language vs C++ has simpler cognitive abstractions, it has more zero cost abstractions, and it has more efficient abstractions overall, both in the language and the standard library.