2020-06-19
Removing unmaintained packages from your Fedora machine should require explicitly opting in
Ben Cotton recently wrote an entry on Fedora potentially removing unmaintained packages from your system under some circumstances, because there is a Fedora change proposing to remove 'retired' packages. The change proposal contains the following remarks:
Upgrade/compatibility impact
During an upgrade, all retired packages will be automatically removed.
[...]
How To Test
1. Upgrade to next version of Fedora. 2. Check all retired packages are removed.
In the ending of Ben Cotton's article, he says in passing "[B]ut we have to make sure we’re clearly communicating what is happening to the user" if package removal happens. I will go further than that.
Removing packages from your system on Fedora upgrades should require an explicit opt-in, and this opt-in should be able to show you the list of packages being removed.
Going beyond that, Fedora should never remove unmaintained packages
from your system without this opt in, for example they should never
push out an updated fedora-retired-packages
RPM in Fedora updates.
Removing unmaintained packages from people's systems is removing functionality with no replacement or equivalent. This can break what people are doing with their Fedora machines, and doing so is both morally wrong and dangerous in practice. It doesn't take too many cases of Fedora upgrades or Fedora package updates breaking things without warning for people to stop doing either of them.
Because this requires explicit user opt-in and a UI and so on, and additional unmaintained packages should not be removed during the lifetime of a Fedora release, I think that removing retired packages during upgrades should live in the upgrader, not be implemented as an RPM package (or at least not as an RPM package that's installed by default). The upgrade system is the only place that is in a position to actively prompt the user in a meaningful way to obtain explicit, informed opt-in consent to this.
(The lightweight version of this would be to require people to opt in in
advance by installing the special fedora-retired-packages
RPM. People
who know enough to manually select and install the package can be
presumed to know what they're doing and be making an informed choice to
accept whatever package retirements Fedora wants to push.)
PS: I was going to consider this different from the existing situation with fedora-obsolete-packages for various hand-waving reasons, but the more I look at what packages Fedora has removed through the fedora-obsolete-packages RPM, the more I think that the two should be mostly merged together and treated very similarly (ie, require explicit opt-in). The current fedora-obsolete-packages goes well beyond merely removing packages that cause upgrade problems (unless you take a rather expansive view of 'upgrade problems').
People's efficiency expectations for generics in 'Go 2' and patterns of use
The Go authors have recently come out with a blog entry on the next steps for generics and a new draft design based on interfaces instead of contracts. As it always is, one of the concerns raised in the draft is about the efficiency tradeoffs of any implementation.
Roughly speaking, there are two ways to implement generics. One is to generate fully specialized implementations every time a generic function or type is specialized to a concrete set of types; another is to compile only a single implementation and quietly pass hidden parameters to the implementation so that it can do its work, similar to how interfaces are implemented in Go (and also maps; most of the code of Go maps is generic, not specialized for each type of map). Fully specialized implementations are as fast as the compiler can make them with full knowledge of the types and functions involved, but they take longer to compile and result in more code in the final binary.
In thinking about this, it strikes me that there are two usage
patterns (or at least extremes of usage patterns) for generics,
based on what code people often write in Go today. I will call these
type safe interfaces and single implementations respectively.
The type safe interfaces usage pattern would use generics to implement
a type safe version of what code is already doing with interface{}
or somewhat more restrictive interfaces today. The proposal itself
talks about Go using generics to implement type safe versions of
things like container/list
and sync.Map (here).
The single implementations usage pattern would use generics to condense
what today is multiple copies of essentially the same code, specialized
to various types, into a single block of code using generic types. These
are the people who are tired of writing yet another copy of the function
to generate a slice of all of the keys of a map of some new type. Their
existing code could in theory be written once using interface{}
and a
lot of typecasts, but in practice repetition is better than all of the
typecasts required (and the resulting possibility of runtime panics),
especially since the underlying code is often reasonably simple and
short.
People in the type safe interfaces usage pattern probably don't mind the potential speed overheads of a single unspecialized implementation, because they are already paying that penalty today. This does imply that such a generics implementation shouldn't perform worse than the interface based equivalent. People in the single implementations usage pattern are replacing hand specialized Go code with a generics implementation so they can write it only once. Some of them won't be willing to do this if there's a significant performance penalty as a result of such a conversion, and in general these people are willing to pay the compile time and space penalty for specialized implementations because they're already doing so today with their hand specialized code.
(Hopefully the Go compiler can find clever ways to often make the extra cost of unspecialized code very low, similar to how it implements maps efficiently.)