Packaging Rust for Fedora
Packaging Rust for Fedora
Posted Oct 28, 2022 15:33 UTC (Fri) by q_q_p_p (guest, #131113)Parent article: Packaging Rust for Fedora
Rust doesn't even support separating interface from implementation, and wastes resources be requiring every dependency to be recompiled for every program.
Now rewrite LLVM in Rust - what will you get? Few hours of compilation for every program that depends on it. Have Fun.
Posted Oct 28, 2022 16:47 UTC (Fri)
by tchernobog (guest, #73595)
[Link] (40 responses)
cbindgen is able to generate the C/C++ headers for your library from the Rust code. So I don't get your point here.
> Rust doesn't even support separating interface from implementation,
Which is only needed in languages designed in the '70s - '80s, like C?
Even C++ is moving towards not requiring this anymore, with C++20 modules.
The performance hit is negligible, if not actually beneficial because the compiler has more information earlier (e.g. to mark what to inline).
> and wastes resources be requiring every dependency to be recompiled for every program.
This is where a global cache, like it was proposed for Fedora, would be appreciated.
The problem is not trivial because of Rust package features; but it's not like a change in, say, the features enabled in OpenSSL during the ./configure step might not force you to have to recompile all reverse dependencies. All of this can be resolved by just being a bit disciplined and writing modules for Rust rather than compile-time features. It's a software engineering problem, not a language issue.
And let's recall that languages such as C++ don't have a well-defined ABI anyway (even name mangling is not part of the standard). C gets away with it mostly because a lot of stuff is missing from function signatures. But I've lost count of the amount of times I saw breakage at runtime because of it.
tl;dr: I don't think Rust here is much different than other compiled languages, if cargo is integrated properly with the rest of the packaging system.
> Now rewrite LLVM in Rust - what will you get? Few hours of compilation for every program that depends on it. Have Fun.
Just use shared libraries? You seem to be under the impression Rust doesn't support them.
Posted Oct 28, 2022 17:51 UTC (Fri)
by khim (subscriber, #9252)
[Link] (8 responses)
Rust doesn't really support shared libraries. swift does, though and Rust-the-language forces traits model which makes that support not impossible in the future. That's hard task, though, not something you may demand while Rust developers are doing that development on shoestring budget.
Posted Oct 28, 2022 19:33 UTC (Fri)
by tchernobog (guest, #73595)
[Link] (7 responses)
Else, you can opt to stick with the same rustc version for a few years, and the unstable ABI producing dylibs (".rlib") will be enough.
I mean, it's not like Perl gets upgraded on my Debian system without hundreds of modules going through a mass rebuild. And C++ ABI got calmer only with libstdc++ versioning.
I am just saying: it's not a particularly new film we are seeing. Nor one which has an unsolvable scenario, given enough willingness to fix it.
Posted Oct 28, 2022 21:08 UTC (Fri)
by khim (subscriber, #9252)
[Link] (6 responses)
You can't. Ideomatic Rust is built on top Actually you can't even use other generic types without language support similar to what Swift did. That, basically, means that instead of using shared libraries as, well, libraries, you are creating modules, boundaries of which are almost as hard to cross as boundaries between processes. At this point making shared libraries makes no sense. Too much pain for too little gain. Better to link in network library and go with multiple processes. No. It got calmer when C++ developers have decided: yes, we do want to support shared libraries. Rust developers have never done that. This would have worked if Rust releases, like GNAT releases, happened once a year. And even that would have been problematic (I don't think any distribution releases too many shared Ada libraries). But they are released 8 times a year. That's too much churn to realistically support. You can't go against upstream, basically. If upstream doesn't want to support shared libraries and actively makes that support problematic then they wouldn't be supported.
Posted Oct 30, 2022 13:31 UTC (Sun)
by ssokolow (guest, #94568)
[Link] (4 responses)
Whether or not to build a ...not to mention, Rust's dependency counts are misleading when you're trying to make comparisons, because C and C++ are rife with bespoke reimplementations and single-header libraries that maintainers just take in stride, rather than trying to split out into their own packages. (See the Gotta go deeper section of Alopex's Let's Be Real About Dependencies for details on that.)
Posted Oct 30, 2022 14:50 UTC (Sun)
by khim (subscriber, #9252)
[Link] (3 responses)
No. The important thing is standard library. It's ideomatic to use it in both C++ and Rust. And while it's called Standard Template Library Swift as we all know picked different road, compiler-based. But, again: standard types and standard templates are usable when you build shared library. In Rust land… Rust developers have never done that and not even That means that shared-library-Rust doesn't even remotely resemble normal That's pretty big difference: while in C++ it's possible to write code which would be acceptable both in normal C++ project and in shared library, too… in Rust it's just impossible. Without ability to just return In C++, on the other hand, it's perfectly fine to accept
Posted Oct 30, 2022 15:02 UTC (Sun)
by ssokolow (guest, #94568)
[Link] (2 responses)
Posted Oct 30, 2022 16:51 UTC (Sun)
by khim (subscriber, #9252)
[Link] (1 responses)
There is no free lunch. Either you have ABI-stable standard library or shared libraries are, basically, impossible. And it's not as if Rust standard library can do sudden, radical, changes. It just wasn't in use for as long as C++ one.
Posted Oct 30, 2022 17:09 UTC (Sun)
by ssokolow (guest, #94568)
[Link]
Posted Oct 31, 2022 11:44 UTC (Mon)
by DianaNites (subscriber, #160945)
[Link]
Posted Oct 28, 2022 19:29 UTC (Fri)
by mathstuf (subscriber, #69389)
[Link]
Eh. Splitting still has benefits. The isolation is not as air-tight as some might expect from other languages. For example if you (privately) import module X in your module, some compilers may require that when importing your module, they *also* need to be told where the bits for module X are (there's no way to say "I need X, but it doesn't affect by interface" because what affects the interface is…not an exhaustive list typically). So if X is indeed something that doesn't affect your interface (which includes `sizeof()` any public types), putting it into an "implementation unit" can help consumers not need to care (as much) about X.
I do agree about the reaction of there being no separation. Basically only C and its immediate offspring have it and it is…not a benefit overall. The lack of proper namespacing and isolation is what caused that. Rust has good namespacing and isolation, so it's not actually that much of a problem there.
Posted Oct 30, 2022 1:53 UTC (Sun)
by dvdeug (guest, #10998)
[Link] (27 responses)
> Which is only needed in languages designed in the '70s - '80s, like C?
I'd say separating interface from implementation is needed in every large enough program, at least conceptually. C doesn't do it great; the .h file doesn't stop all symbols from leaking all over the place, and has only hacky ways of hiding information (you can't have a struct without making the details available, though you can have a pointer to a struct without the details for a struct.) Java gets away with it because class files carry the interface information and prohibit abuse of implementation details (at a computer level) and JavaDoc shows just the implementation.
I'm not that familiar with Rust, but I'd say a good language for software engineering needs at least a JavaDoc substitute (for humans) and some effort to keep users from accidentally using implementation details, if it's not going to separate interface from implementation in code. I don't know why everyone has gone away from separate interfaces, but I don't think it's been a good decision.
Posted Oct 30, 2022 10:22 UTC (Sun)
by ssokolow (guest, #94568)
[Link] (7 responses)
They've certainly got the former. Rust's JavaDoc equivalent is unadventurously called rustdoc, it's installed as part of the base toolchain, it doesn't require you to manually opt into documenting things like Sphinx for Python does, you can generate and view docs for your entire dependency tree locally with As for the latter, I don't know what your requirements are, but they certainly make a strong effort. Things like type inference are only allowed inside functions, with function signatures, consts, and statics requiring that you explicitly write out the type signature and structs even requiring you to write out lifetime annotations in places where they could be inferred. There are no exceptions, instead requiring that you declare error paths intended to be recoverable (i.e. not asserts) as part of your return type via The ecosystem has also produced crates like static_assertions (#1 most popular crate in the #compile-time category according to the libs.rs alternative crates.io frontend), which makes it easy to fail the build if invariants like "these two types must have the same alignment requirement" get broken.
Posted Oct 30, 2022 11:07 UTC (Sun)
by ssokolow (guest, #94568)
[Link]
Posted Oct 31, 2022 0:41 UTC (Mon)
by tialaramex (subscriber, #21167)
[Link] (2 responses)
Lifetime elision has been enabled in Rust for some time. For example, suppose our function takes a &str and it returns a &str. We could ask, what is the lifetime of these two &strs ? But it doesn't take a genius to guess that they should probably have the same lifetime, whatever that is. The compiler will try that and, if it works, accept the function despite it not specifying the lifetimes.
Posted Oct 31, 2022 1:03 UTC (Mon)
by ssokolow (guest, #94568)
[Link] (1 responses)
I was referring to how, yes, you can elide lifetimes in function signatures, but you'll get a "missing lifetime specifier" error if you try to do something like this:
Posted Nov 1, 2022 8:28 UTC (Tue)
by tialaramex (subscriber, #21167)
[Link]
Posted Oct 31, 2022 3:36 UTC (Mon)
by pabs (subscriber, #43278)
[Link] (2 responses)
Posted Oct 31, 2022 11:28 UTC (Mon)
by neal (subscriber, #7439)
[Link] (1 responses)
Posted Oct 31, 2022 12:35 UTC (Mon)
by pabs (subscriber, #43278)
[Link]
Posted Oct 30, 2022 13:03 UTC (Sun)
by emk (subscriber, #1128)
[Link]
Rust uses namespaces with the ability to control what gets exported. If it's not exported, you can't access it. You can even say things like "this interface is visible outside of this file, but only inside of this library" (aka "pub(crate)"), or you can export certain symbols only in test mode. Private members of structs are completely hidden, and don't even lie at a predictable offset within the struct. A number of other features, like the orphan rule and trait member visibility, are designed specifically to prevent weird surprises. But Rust doesn't implement this using header files; it's built directly into the language.
Rust libraries are almost precisely limited to what appears in the documentation. And as other posters have noted, Rust's doc tools are solid. By default, if you put sample code in the docs, Rust even compiles and runs it as a unit test. (You can mark individual code snippets "no_run", which will cause Rust to only compile them.)
Posted Oct 30, 2022 17:01 UTC (Sun)
by khim (subscriber, #9252)
[Link] (17 responses)
It was absolutely good decision because it's bad idea to ask people to do things which computers can do better. You never need implementation part alone, that's just never usable for anything. You need interface and implementation if you are developing library and you need just the interface if you are using that library. And it makes much more sense for the computer to take the whole thing and remove implementation (like both
Posted Oct 30, 2022 19:30 UTC (Sun)
by dvdeug (guest, #10998)
[Link] (16 responses)
In semver terms, the interface can not be touched in a patch level change, it can be added to but what was there can't be changed, and it can be arbitrarily changed in a major release. Even internally, the interface can't be unilaterally changed without touching other files.
Mixing interface and implementation makes it harder for the programmer to see what changes are breaking the interface. Making the interface into the implementation is usually a copy command and a few minor edits, and the computer could easily keep them compatible. Either way, the computer can help the issue, but I've seen nothing that highlights interface changes or otherwise makes them obvious to the programmer.
Posted Oct 30, 2022 20:34 UTC (Sun)
by khim (subscriber, #9252)
[Link] (14 responses)
Not perfectly. Default implementation of methods for these interfaces (like with Rust analogue) goes in the file where interface is described. And you can add classes to them, too: Yes. That what I hate about Java most. Not about Java-the-language, but about Java-the-ecosystem. Useless pile of abstractions where the actual code is very hard to find. Why would you make every class mockable? What's the point? What are you trying to achieve? There are no implementation inheritance in Rust which means 90% of problems which this total mocking is supposed to fix just don't exist! Traits are a bit harder to abuse for that, but, more importantly, Rust doesn't consider blind cargo-culting a viable way to write code. Maybe if you randomly change your code. Yes, trait definition goes into the same file as it's implemntation, usually, but in practice it's not hard to notice whether change is modifying trait or only it's implementation (just look for It's same in Java. If you replace
Posted Oct 30, 2022 20:47 UTC (Sun)
by mpr22 (subscriber, #60784)
[Link] (13 responses)
If every class is mockable, then a unit test of class Fred can use mocks of any classes that class Fred invokes.
This is highly attractive for some people.
Posted Oct 30, 2022 21:33 UTC (Sun)
by khim (subscriber, #9252)
[Link] (12 responses)
That's not the answer why they like to compulsively mock everything endlessly. If someone likes to get drunk it's not a good reason to make alcohol more easily available to him (or her). Note that C doesn't allow you to easily mock something and yet Linux kernel is more reliable than creations of these guys who praise Java for the easy mockability of everything. Which means mockability doesn't translate into higher reliability. If people do understand why they need to mock everything religiously (and that still doesn't help entirely) then it would be easy for them to see why they don't need that in Rust. If they don't understand where and why that cargo-cult started then I don't see why we need to even help them. P.S. Hint: it starts with L and includes the name.
Posted Oct 30, 2022 22:54 UTC (Sun)
by dvdeug (guest, #10998)
[Link] (11 responses)
> Which means mockability doesn't translate into higher reliability.
That's a ridiculous comparison. You're comparing a kernel which has had some of the best programmers in the world work on it to ... everything ever written in Java?
Mocking a class permits testing just that exact class in isolation. That has clear advantages for testability and hence for reliability. Is it the best tool? I don't know, but the interesting question for most users is how does it work for standard business programmers working under time pressure, not how does it work for Linus Torvalds when he's been working on the same program for 30 years.
Posted Oct 31, 2022 0:53 UTC (Mon)
by khim (subscriber, #9252)
[Link] (9 responses)
No, just typical “enterprise app” whose development cost comparable sum to what development of kernel cost. And you can not say that kernel is written by “some of the best programmers in the world” and then turn around and claim that they just don't understand the good design when they see it. Nope, you don't need mocks for that. If you class permits the disconnect in production (e.g. if you permit choice of either mysql or postgresql) then you can change that part for testing. If there are no possibility of separating two components or classes in production then why the heck do you want to separate them in your tests? Mocks are not the way to test interfaces, they increase coupling instead of decreasing it! Quite the contrary. Simple example: suppose I have a parser and I decided to improve it's performance by adding some buffering to it… it would pass all tests you can imagine without mocks… but mocks would make it fail (because mock wouldn't provide enough data to fill the buffer). Now, I have to change mocks and would make them match new expectations from what must be provided for my parser — which means I'm writing new code without tests (there are no tests for mocks because if you start going that way when would you stop). And it's easy to write mock in a way that it always fills the buffer requested and never returns less data then what was requested (unlike the real thing). Eventually you reach the state where your mocks model everything badly and incorrectly. And then your tests pass but code throws exceptions left and right if it can be used at all. Yes, mocks allow you to test code in isolation, but that's a problem, not an advantage. It reduces reliability of the whole system, not increases it. Some even say that they only way to properly test something is to test “everything like in production”. I wouldn't go as far, but the larger piece of your system is covered by a single test then higher chance it gives to you that test verifies something important. Mocks go in the opposite direction and thus are not needed nor desired for reliability. Try again. Maybe, but from observations it doesn't work all that well for them either. Git (entirely new project) went from rought idea to usable product much faster then any Java-business project I know. And yes, I know that Linus Torvalds is brighter than “most standard business programmers”. That wasn't the big reason. The big reason was that Linus knew what he wanted and he knew what tests he needs and what tests he doesn't need. “Standard business programmer” just does motions which were designed to achieve things he doesn't know about and then tries to fix issue which not need fixing while simultaneously missing things that do need fixing. It's telling that you couldn't event explain what property mocks are trying (and failing) to achieve and which, indeed, is hard, almost impossible to test without mocks in Simula67-style OOP languge like Java.
Posted Oct 31, 2022 2:30 UTC (Mon)
by dvdeug (guest, #10998)
[Link] (1 responses)
https://lwn.net/ml/linux-kernel/CAHk-=wj6y5fipM2A5kEuOO9q... lists over 100 contributors to Linux 6.1-rc1. Assuming that has lasted over the past 30 years, I don't know how many enterprise apps there are with 3000 man years in them.
> And you can not say that kernel is written by “some of the best programmers in the world” and then turn around and claim that they just don't understand the good design when they see it.
That's not what I said. I will say that the best anything in the world frequently don't understand how the average person in a field can best do something.
> Some even say that they only way to properly test something is to test “everything like in production”.
Which is a cause of a huge number of bugs. For one thing, the hardware your code will run on in a few years usually doesn't exist. For another, it's hard to predict what production will be like. At worst, that comes down to "it works on my system".
> The big reason was that Linus knew what he wanted
Yeah, I don't think a single programmer writing a source-control system to his own whims is very closely related to writing a large team writing code to external specifications.
Posted Oct 31, 2022 7:49 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link]
Amazon has something like 50000 developers working on AWS. I believe Microsoft and Google have similar numbers. Even given that the average AWS developer is far from the level of kernel developers, the aggregate amount of code that they produce is staggering.
You really underestimate the size of modern large applications.
Posted Oct 31, 2022 8:18 UTC (Mon)
by Wol (subscriber, #4433)
[Link] (5 responses)
> The big reason was that Linus knew what he wanted and he knew what tests he needs and what tests he doesn't need. “Standard business programmer” just does motions which were designed to achieve things he doesn't know about and then tries to fix issue which not need fixing while simultaneously missing things that do need fixing.
Which is why I bang on about how Pick projects are better than SQL. Pick makes programming accessible to the END USER. Which is why projects actually do what is required at the first attempt!
Okay, without proper programmer/analyst input right from the start, the result can easily be a horrendous ball of spaghetti, but when you have programmers and end users working TOGETHER, then the result is brilliant. Far too many projects, the end user tells the analyst what they want, the analyst specs the system, then maybe the designer designs it, before the programmer writes it. Chinese Whispers all the way. The programmer never sees an end user, half the people in the chain are clueless as to what the system is really wanted to do, and the result is a late, over budget, half-implemented ass of a solution.
Cheers,
Posted Oct 31, 2022 12:04 UTC (Mon)
by khim (subscriber, #9252)
[Link] (4 responses)
SQL is awful abomination in theory, but there are many decent free implementation which work reasonably well in practice. Pick is better in theory but there are no decent free implementations which makes it non-starter for many projects. I would love to use Pick instead of SQLite for my [pretty] modest needs but SQLite is free and integrates very well with other tools which Pick… Well, maybe someone would solve that problem. Hey, before Rust I was 100% sure the mistake that world made quarter century ago (when it picked OOP and GC as the main road which obviously leads us nowhere) would never be fixed. Maybe something like that would, eventually, happen with databases, too?
Posted Nov 1, 2022 12:47 UTC (Tue)
by Wol (subscriber, #4433)
[Link] (3 responses)
I've just been involved in a migration from SQL/Relational to SQL/Relational. It's over-run its cost budget, it's over-run its time budget, it's been a bit of a disaster ... (Not in causing any real problem to the company, but just in the endless delays ...)
Part of this has been "where is this field defined?". We've got assorted measures like DPR (part of our efficiency metric), which is calculated in god-only-knows how many places, the definition has chnged over time, where the hell is the current definition and is it used consistently ...
Because Pick does NOT distinguish between tables and views, because Pick has virtual columns, because Pick is (or can be) object orientated, it's EASY to have just the one definition, in the one place, and THAT'S IT. As soon as you try defining virtual columns in Relational, they end up strewn over multiple tables, and managing it is a nightmare.
Then there's the simplicity of defining your FILE. You define your Real columns just like in Relational. Then because Pick defines by iterating through rows, you define your Virtual columns with a function like Excel vlookup. You don't have this horrendous 100-line (if you're lucky enough for it to be that small) abhomination of a SQL view. So your virtual field is defined as part of the FILE that is the object of interest, and if you need it anywhere else, you just create a virtual field that references the master definition and pulls it across.
Can't remember whether I said, but seeing as I'm going to be integrating ScarletDME with Google Sheets and BigQuery, it comes with an Excel connector, there's a whole bunch of JSON, web, whatever connections available if you want it ... if you've got time to play download it, reach out to me if you want, go onto the relevant google groups, and I'll do everything I can to help ...
Cheers,
Posted Nov 1, 2022 15:41 UTC (Tue)
by kleptog (subscriber, #1183)
[Link] (2 responses)
Posted Nov 1, 2022 15:58 UTC (Tue)
by Wol (subscriber, #4433)
[Link] (1 responses)
(Oh, and 20kb queries aren't the problem. It's queries that are hand-written and huge. And by the way, the guys expected to write the queries are NOT database bods, they're end users who need the information. (And without whom, there's no point having a database!!!))
Oh - and if ORM means "Object Relational Model", then just ditch the relational and use Pick instead :-)
Cheers,
Posted Nov 1, 2022 23:24 UTC (Tue)
by ssokolow (guest, #94568)
[Link]
Posted Dec 3, 2022 6:38 UTC (Sat)
by ghane (guest, #1805)
[Link]
This. Precisely this.
Developers keep opening issues that make no business impact, and keep trying to solve every issue with a combination of StackOverflow and copy/paste.
This week, I have been trying to explain to a team why they should remove an "UpdatedAt" database field from a table that is an immutable append-only log. "But every other table has a CreatedAt and UpdatedAt field!"
Meanwhile, users see "Oops an Error happened" popups. "OK" button.
Posted Oct 31, 2022 13:55 UTC (Mon)
by mathstuf (subscriber, #69389)
[Link]
I think you mean "things using that class".
However, I have managed to get away with zero "class mocks" in my Rust code as well. The `#[test]` attribute allowing tests to be written right beside the code under test helps a lot as it also means that Rust's visibility rules allow the tests to reach "behind the curtain" to do things as necessary (for setup or validation). About the only thing I've mocked is remote services which…are easy to mock without mucking with the actual code since the codebase is abstracted over remote implementations already (GitLab or Github), so adding one that just uses in-memory storage and a tempdir for all of its bits is easy enough.
Posted Oct 31, 2022 4:25 UTC (Mon)
by ssmith32 (subscriber, #72404)
[Link]
And the correct answer is always "no".
Because:
This is from working at several different companies on largely Java codebases. New Java folks come in and having read some book by Crazy Uncle Bob or some such nonsense, and they learn quickly that it's not a good idea.
Interfaces should only be used when you *need* multiple implementations. And, no, your hand-rolled mock does not count. You should have used Mockito.
Posted Nov 1, 2022 10:30 UTC (Tue)
by paulj (subscriber, #341)
[Link] (1 responses)
Ooh, that's a good idea. And the cached compiled modules would of course need versions attached, cause at any given point you may have some binaries that are recompiled against the number modules and some that are not yet. At some point, particularly for energy efficiency on lower-powered devices and efficiency where you have a multitude of machines (large DC), you may wish to just provide these cached, compiled modules as a ready-made package. So you need a globally co-ordinated versions numbers (or at least, sufficiently wide in scope for your situation). Then you can provide foo-modules RPM package, that other packages can rely upon.
Yes, this sounds like a radical improvement on libraries. ;)
Posted Nov 1, 2022 13:14 UTC (Tue)
by Wol (subscriber, #4433)
[Link]
As I understand it, this keeps multiple copies of dlls, so that you DON'T overwrite an old version with a new one and screw up programs that rely on the old version. So what we want is shared, versioned liberaries, that are happy to share if they're using the same version, but don't trample over someone else's *different* version of the same libary.
Bit like a curated crates setup - if they can make that do that, you'll only have one copy of each crate, and hopefully they'll have some mechanism whereby you can update the crates manifest/linkage without having to relink the program, so if it all goes pear-shaped with a new version, you can revert the link-update.
Cheers,
Packaging Rust for Fedora
> Just use shared libraries? You seem to be under the impression Rust doesn't support them.
Packaging Rust for Fedora
Packaging Rust for Fedora
> You can use Packaging Rust for Fedora
#[repr(C)]
if you want a stable ABI now.
Option<T>
and Result<T, E>
(some language construct don't even accept anything else!) — and these are not #[repr(C)]
.Packaging Rust for Fedora
No. It got calmer when C++ developers have decided: yes, we do want to support shared libraries. Rust developers have never done that.
cdylib
from a Rust project is certainly a choice upstream makes, but also bear in mind in mind that, unless things have changed since 2012 on the ABI compatibility front, many of the core issues are just as unsolved in C++... it's just less idiomatic to rely on things like templates in C++ than on things like generics in Rust. (See The impact of C++ templates on library ABI by Michał Górny from 2012 for more on that.)
> it's just less idiomatic to rely on things like templates in C++ than on things like generics in Rust.
Packaging Rust for Fedora
libstdc++
developers have decided that they would find a way to make it work as shared library. And they did. Yes, templates are injected in your code, not in the shared library, but certain discipline on the side of libstdc++
developers made it possible.core
is offered in a way suitable for use in shared libraries.std
-based Rust. While in C++ the part which can be used as shared library is very much a subset of what you would do in normal C++.Result
or accept Option
your code is not Rust, it's different language.std::option
or pass std::unique_ptr
even in function which is part of shared library.
Fair point... though an argument has also been made that C++'s focus on ABI stability is killing the standard library.
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
There is no free lunch. Either you have ABI-stable standard library or shared libraries are, basically, impossible.
Or you marshal your data in some way, like the abi_stable crate does for enabling dlopen
-able libraries using higher-level Rust constructs via Rust-Rust FFI through the C ABI.
And it's not as if Rust standard library can do sudden, radical, changes. It just wasn't in use for as long as C++ one.
The Rust standard library has two advantages over C++ on that front:
HashMap
implementation for a vendored copy of a port of Google's SwissTable. There's currently a PR being refined to replace the internals of std::sync::mpsc
with a vendored copy of crossbeam-channel
.)Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
cargo doc --open
, and every crate that's published to crates.io automatically gets rustdoc run on it and the result hosted publicly at docs.rs. (Though the docs.rs run is configured to only display the README for binary/non-library crates, unlike cargo doc
.)
Result<T, E>
. There's no such thing as "is this class POD?" (You ask for dynamic dispatch by taking a (data, vtable)
fat pointer to the object). There are various language features such as method overloading where part of the reason they don't exist is "the interaction with type inference would leak implementation details into the ABI stability characteristics". etc. etc. etc.
Packaging Rust for Fedora
"the interaction with type inference would leak implementation details into the ABI stability characteristics"
I keep forgetting not to post in the middle of the night. I meant "API" here.
Packaging Rust for Fedora
I've been using Rust since 1.0. I know what lifetime elision is. Maybe my phrasing wasn't clear enough that the "even requiring you to write out lifetime annotations in places where they could be inferred" was scoped to the "and structs", not the entire sentence.
Packaging Rust for Fedora
struct Thing {
inner: &str,
}
When lifetime elision was implemented, stopping there was a conscious decision.
Packaging Rust for Fedora
Packaging Rust for Fedora
In Sequoia, we started generating man pages from the clap data structures. It works much better than help2man.
Packaging Rust for Fedora
Packaging Rust for Fedora
> I'm not that familiar with Rust, but I'd say a good language for software engineering needs at least... some effort to keep users from accidentally using implementation details
Packaging Rust for Fedora
> I don't know why everyone has gone away from separate interfaces, but I don't think it's been a good decision.
Packaging Rust for Fedora
Javadoc
and rustdoc
are doing) then to ask human to mentally combine them when s/he tries to do development.Packaging Rust for Fedora
> Java has "interfaces", which are different from the type of interfaces we're talking about, but can be used to separate interface from implementation.
Packaging Rust for Fedora
interface MyInterface {
void interface_not_implementation();
static class MyImplementation implements MyInterface {
public void interface_not_implementation() {
System.out.println("Someone talks about separation?");
}
}
}
> And many people online ask if every class should have an interface; among other things, that makes the object mockable.
impl
keyword).Object
with T
then it's backward-compatible change as easily can be seen, but nothing highlight that AFAICS. Same as with C or Rust: you have to look on the change to understand whether it's backward-compatible or not.Packaging Rust for Fedora
> This is highly attractive for some people.
Packaging Rust for Fedora
Packaging Rust for Fedora
> You're comparing a kernel which has had some of the best programmers in the world work on it to … everything ever written in Java?
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
Wol
> Which is why I bang on about how Pick projects are better than SQL.
Packaging Rust for Fedora
Packaging Rust for Fedora
Wol
Packaging Rust for Fedora
Packaging Rust for Fedora
Wol
They're probably lumping anything with a query builder API under "ORM", even though things like Python's SQLAlchemy make the Object-Relational Mapper layer an optional higher-level wrapper around the lower-level query builder system.
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
Packaging Rust for Fedora
- It pointlessly doubles the number of files you have to deal with.
- It pointlessly increases how long it takes to navigate from a call site to an implementation when debugging.
- It doesn't "make an object mockable". Because you can mock objects just fine without them. Mockito, et. al.
Packaging Rust for Fedora
Packaging Rust for Fedora
Wol