[Haskell] URLs in haskell module namespace

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Wed Mar 23 08:11:21 EST 2005

"S. Alexander Jacobson" <alex at alexjacobson.com> writes:

> Ok, well lets unpack what is actually required here:
> 1. Change of syntax in import statements
> GHC already has lots of new syntax.

I can see that one might wish to broaden the import syntax, rather
like Hugs once supported (but not now) to use a full filepath rather
than a module name.  For parsing, a URI enclosed in string quotes
would be easiest.  However, I suspect that the same reason why Hugs
abandoned filepaths, will arise here again.  I don't know what that
reason was, but would imagine that non-local absolute links are
very fragile.  The better solution to my mind is to (a) include all
the local source code in a local relative directory/namespace, and (b)
have any non-local modules referenced by package name, not location.
The package name is likely to be constant, whereas its location
(whether on the build machine or the wider net) is likely to change.

> 2. Module names with package scope
> GHC already has a -i.  I assume the complexity of generating a -i 
> w/r/t a notation provided in the import statment is not that high.

I don't see a problem with adding
    {-# PACKAGES gtk2hs furble #-}
to the top of a source file.

> 3. Networking Client
> I think GHC already bundles Cabal and Cabal already handles being a 
> network client and doing some database mapping.  (Lemmih: Please 
> correct me if I am mistaken).

Cabal just does packaging.  It is the Hackage project which does the
networking stuff to make the finding and downloading of packages easy.

> Also, it is ridiculous for a modern 
> language implementation NOT to have a network client library.

Of course the /language/ should (and does) have a network client
library.  But should every compiler expect to do networking stuff?  No.
For one thing, there is a huge number of machines out there with no
network connection, whether for security or otherwise.  What do you
propose the compiler should do there?  Inevitably, you are going to
need some other tool, running on a different, net-connected machine,
to collect the necessary library packages for physical transfer.

> 4. Caching
> Caching is new, but it is not that difficult to add to an extisting 
> HTTP requester and the benefits seem well worth this marginal cost.

Network caching belongs in a separate layer of the system environment -
middleware if you like.  It is a service unrelated to compilation.

> 5. Maturation of Packaging Tools
> I agree that the packaging tools are immature.  That is why it makes 
> sense to evaluate this proposal now.  No one has a big investment in 
> the current packaging model and packaging tools optimized for a 
> language that works in the way I propose would look very different 
> from packaging tools organized for the pre-Internet world.

Fair enough.  Just don't assume that every machine now or in the
future will be net-enabled.

> > No, it spreads the dependency problem over lots of import statements,
> Disaster?  I don't think so.  That is why purl.org exists.  The HTTP 
> 302 status code is your friend.  If you don't want to use purl.org, 
> feel free to set up your own redirect server.  I imagine various 
> different redirect servers operated by different people with different 
> policies about what counts as a bug fix vs what counts as a new 
> version, etc.

Hmmm, this is pretty much what Hackage aims to provide.  Give it a
package name, and the tool will resolve it to a location and download
the package.  It will likely support multiple servers with different
policies, and you simply configure which servers you want to use.

> And btw, it is a failure of Haskell right now that imports don't 
> create dependency.  Right now, I would like a sane way to import two 
> different versions of the same module so I can do file conversion.  It 
> seems like the only way to accomplish this in Haskell as it stands 
> is to rename one version and then I'm back in the world of global 
> search and replace on import lines again.  It would be MUCH 
> niceer do this via packages URLs instead.

I think this will be trivially possible once the compilers support
multiple versioning of packages.  (Ghc may even support it already.):

    {-# OPTIONS -package foo-1.0 #-}
    module Old (module Foo) where
    import Foo

    {-# OPTIONS -package foo-2.2 #-}
    module New (module Foo) where
    import Foo

    module Convert where
    import qualified Old
    import qualified New
    convert (Old.Foo x y) = New.Foo y x

> > It would be much better to group the dependencies into a single
> > file per project - so there is just one place where changes need to
> > be made.  This possibility already exists - just create a .cabal file
> > for the project.
> How do I depend on multiple versions of the same package in a single 
> module?

You can't do it in a single module, because the namespaces overlap.
But it should be straightforward using two or more modules, to separate
out the namespaces via qualification, as illustrated above.

> How do I make sure that my .cabal file is up to date with the 
> actual content of my imports?  I am proposing to automate this 
> process.  You appear to want to keep it manual.

No, automated would be better.  I believe Cabal is moving in the
direction of automatic dependency generation from the source code.
It will initially be rather like hmake or ghc -M, but should probably
also be extended to determine package names and versions too.

> > The Hackage project is exactly a database of package/location mappings,
> > which the /author/ of each package can keep up-to-date, not the user.
> > Much more maintainable.
> See my comment to Lemmih about the possibility of multiple hackage 
> servers and needing to know locations on each of those servers.

Yes, but storing one or two stable server locations in a config file
is much easier than searching out lots of package locations.


More information about the Haskell mailing list