6 ms·
For example, before we had something like: top: *const FFISafe<WithOffset<&'a u8>> We can change that to: top: WithOffset<*const FFISafe<&'a u8>>
by dmitrygr 10mo ago
For example, before we had something like:
top: *const FFISafe<WithOffset<&'a u8>>
We can change that to:
top: WithOffset<*const FFISafe<&'a u8>>
rust, you were meant to replace c++, not join it...
- saghm 10mo agoThe point of Rust is ostensibly to provide a safer version of C++-like semantics, not necessarily to avoid the same level of complexity. Especially if you're directly using unsafe code (which is necessary in some cases, like FFI), it's not really clear to me that Rust was "meant" to be doing something wildly different here. The large majority of the code not needing to use unsafe will still be better off even if this type of thing is necessary in some places. (To preempt any potential explanations about this: yes, I understand the reference being made with that quote. I just don't think it actually applies here at all)
- zephen 10mo agoThis 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.
- 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.
- mpyne 10mo ago> rust, you were meant to replace c++, not join it... Turns out that not all of the C++ noise people make fun of is due to C++, sometimes the problems you want to solve with Rust or C++ is just hard to express simply to the compiler.
- bnolsen 10mo agoAnd then zig shows up...
- Aurornis 10mo agoFYI to non-Rust devs wondering what's going on with this code: Those two abstractions (FFISafe and WithOffset) are not standard Rust abstractions. They're something the author is building within their own library: https://github.com/memorysafety/rav1d/blob/25e5574/src/ffi_safe.rs#L11 https://github.com/memorysafety/rav1d/blob/25e5574/src/ffi_s... So for all of the complaining about Rust abstractions and syntax in this thread, keep in mind that these particular abstractions that caused this problem are not standard. If you just want to call an extern "C" function you can do so directly in an unsafe block. The article should be read as the author debugging their Rust wrapper types, not as a generic article about calling C functions from Rust.