This thread has become quite lengthy, and I apologize if I missed it, but what happened to Taylor’s suggestion:
This is what other ecosystems do, and it works incredibly well.
I also dislike that names on Hackage are given away for free, while there is no possibility of taking them back. I mean, an evil actor could reserve a ton of important names without much problems.
Namespaced package are the default, and it’s very simple to create one. Maintainers have near-full control.
You can optionally apply for a global/public name without your namespace prefix, but you have to pledge maintainership and have fever privileges, e.g. hackage trustees are allowed to give control over that name to someone else if they believe that the other person will be a better maintainer for the community
I don’t see how namespacing is any different than me forking basement and uploading ambroses-non-shitty-basement to hackage tho. I guess more granular tooling?
Oh is it because I can point my package solver at the new namespace? That works but it’s basically the same as an overlay.
I mean..in that case..why not kick this can to cabal? Let me say “solve package name X as name Y” in my cabal.project. No need to have a syntax level namespace thing.
boom - “solved” (except now everyone depending on basement forever has to have the same piece of duct tape in their project lol. namespaces are the same here tho ofc)
Namespacing forces you to use @ambrose/non-shitty-basement, and everyone else. So noone can just take the basement name like that and make beginners think “oh this must be a great package, I’ll depend on it”
cabal.project is great to work around this locally. But only the .cabal file is distributed, so the cabal.project workaround doesn’t work for transitive dependencies.
It’s fine. The decision is for a project (“in this house we use ambroses-non-shitty-basement” for all of the dependencies).
But the actual work should be done somewhere around ghc-pkg so it can pull the package in question to a local registry and do the translation. Aaand this looks suspiciously Backpack
Hm.. If the namespaces are first class, then we can keep the package names and should remap only @hackage/package/@awesome/package to package, then we’re done.
Still not solves the “someone rage-quit while squatting on @hackage/ namespace” problem which is a policy problem, not a technical one.
Personally, I’m okay with fork-and-rename and the resulting churn. Things happen.
What I really want to see here, both as a maintainer of packages and a developer of projects, is the red flag on the packages that are known to be abandoned.
We already have an opt-in “deprecated” package. BTW, can’t the trustees use it on the vincentverse?
I’d like to have “outdated”/“soft-abandoned” flags that will signal that the package is on the way to bitrotland.
The very first thing I do when searching for the package is to click twice on the “last updated” header in the results to focus on what’s minty first. And only go spelunking when there’s nothing matches in the current maintainerocene layer.
In this particular case it is quite clear, as the author was explicit about this.
Six months? Two years? Not building with X versions of GHC? What if a maintainer just keeps uploading new revisions, but neglects what people want? What if they take the package in a direction everyone hates? What if they keep it building but refuse to patch security bugs?
And while those are important problems to solve… let’s not let the mission creep prevent us from addressing the immediate problem.
This was addressed upthread. The minimal criteria on hackage that a package is required to be intended to be useful to others (at time of upload) already prohibit namespace-squatting.
In the age of LLMs, I can just produce a technically-useful library for about any useful name. Usefully trained on the weighted average of all of Hackage. It’s useful because I trained it existing useful stuff. But it was free to make and now I can say I’m done with it but keep the name for free
I like this, but I’m toying in my mind with a slight adjustment: you get a non-prefixed name by default. If I’m the first person to publish a package named acme-missiles, then I get both @philh/acme-missiles and a global acme-missles pointing at it. Someone else can publish @hilph/acme-missiles, and it doesn’t need to have any relationship to mine but conventionally it would be a fork.
We’d expect users typically specify just acme-missiles. If I’m a bad maintainer, a hackage admin can point that name at hilph’s version, and the ecosystem gets updates for free; anyone who wants to get ahead of the hackage admins can explicitly specify hilph’s copy, and anyone who thinks they’re making a mistake can explicitly specify mine.
This still means that the global namespace gets eaten up over time. Maybe someone creates a cgi (as in Common Gateway Interface) in 1995, and in 2025, it hasn’t compiled or even had any forks that compile for a decade. Someone still can’t, by default, say “I want to create a package for computer generated imagery”, call it cgi, and get the global pointer. I think this is fine?
Whether or not my above idea is a good one, I think we want this.
We can already kinda do it with “solve package X from github repo at URL Y”, right? But explicit support would make it a lot more ergonomic.
I do think there are awkward questions around: suppose I depend on a and b, which both depend on x. x gets forked into x2, and a updates to use that but b doesn’t. I say “x is provided by x2 instead”. Are types x2:X.T (visible to me via a) and x:X.T (visible to me via b) the same type? We can’t get into this situation with github right now I think, because if you point at a github repo it needs to know what name you use it as.
I also think that an option for not getting the global package name by default would be appreciated as there are many work in progress hackage packages that don’t need a spot on the global namespace. I’d include my package under that label.
I do think there are awkward questions around: suppose I depend on a and b, which both depend on x. x gets forked into x2, and a updates to use that but b doesn’t. I say “x is provided by x2 instead”. Are types x2:X.T (visible to me via a) and x:X.T (visible to me via b) the same type? We can’t get into this situation with github right now I think, because if you point at a github repo it needs to know what name you use it as.
I would expect x2:X.T and x:X.Tnot to be the same type. They would only be the same type if a and b were “instantiated” with the same variant of x. This is how module identity works in Backpack.
It’s fun to think about possible syntax for package override. What if we extended the build-depends: stanza in .cabal files like this:
So the awkward thing about this is, if my package relies on a and b sharing an X.T type, then a updating to x2 breaks my code in a way that I can’t fix just by saying “okay, x is provided by x2 instead”.
But deciding that they are the same type feels like it also opens up a bunch of cans of worms, I’m just not sure what cans exactly.
I’m not sure, but I feel like the right place for this decision is cabal.project and stack.yaml files. Maybe .cabal files also get to offer hints, but that feels complicated. (Imagine a depends on b depends on c, all of them depend on x, and all of them have different opinions about what should be used to satisfy that dependency. IIUC this problem goes away with cabal.project and stack.yaml, because we only look at one of those files, not a tree of them.)
By way up update, today, my original motivation now looks like this, as the tls universe has significantly reduced its dependency on unmaintained Vincent Hanquez packages:
If @ApothecaLabs succeeds in replacing memory with a maintained alternative, and crypton could be weaned off its direct dependency on basement, then Stack would be free of dependencies on Vincent Hanquez packages.
I guess you could just copy and paste the basement code into crypton directly if that’s the only issue? Ofc it would be better to do more than that, but that’s a quick and effective way to sever the limb.
do you actually want a re-design of memory, or just a drop in replacement with the basement parts ripped out? I’ve been experimenting on crypton and was able to just replace all basement parts with existing stuff in base or other packages such as base16 or deepseq
My own desire is simple: the Stack project’s stated aims include “to depend on well-known packages”, and I would like to eliminate (or, at least, reduce) its (direct or indirect) dependency on unmaintained packages (even well-known ones).
I can’t speak for Kazu Yamamoto (the maintainer of crypton) but I hope he would be receptive to pull requests that reduced its dependency on unmaintained basement.