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.