hsguid is a program to facilitate the creation of immutable and portable interfaces for Haskell libraries. The idea is that you assign a globally unique identifier or GUID to each interface that a library exports. The library can be extended and moved about at whim without affecting any apps which use it since it's interfaces will always be available via the GUIDs. Users benefit because they can freely upgrade their compiler or libraries and be confident that their old code will compile without modification. library developers benefit because they are free to extend their libraries without worrying about backward compatibility, even if they want to start from scratch they can copy the old version to an out of the way place and users will still find it via its GUID. the GUID pragma is also a convenient way to export 'stable' subsets of ones API or multiple views of the same library.
library developers simply add GUID pragmas to their code when they wish to export interface changes. library users (or the library packager) simply runs the hsguid tool over the libraries and it spits out the appropriate stub modules.
pragmas are of the form
{-# GUID <export list...> #-}
.
The export list is of the same format as in the module definition at the top of
the file with the addition of being able to declare aliases of the form
foo as bar
this will export foo under the name bar.
Aliases are useful for exporting older versions of functions under names which
would conflict with newer versions of said functions. A single hs file may
contain any number of GUID pragmas.
{-# GUID 7b38eedb912e0b39df815bc3570598b154e51dd4 sha1, sha1ShowHash #-}some people like silly names for their functions...
{-# GUID c21ed3d234c7b6ef4e7f5d3be54edc13dadbf23a sha1 as doTheShaw, sha1 as okaySeriouslyDoTheShaw #-}a more advanced one.
{-# GUID a17be270380e5d4398804d3c176ab140ad06a6ad sha1, -- this is the standard module GUID_c21ed3d234c7b6ef4e7f5d3be54edc13dadbf23a -- and everything from this one -- note that dash-dash comments may be used in a GUID pragma. #-}
Usage: hsguid [OPTION...] files... -v --verbose verbose mode -V, -? --version show version info -g --generate generate a new GUID -o DIR --output=DIR directory to output GUID modules toThere are two main modes of operation for hsguid.
./hsguid -g
will generate a new GUID for use in a Haskell
module on stdout. a sample output would be
{-# GUID 9acc9d35cf0a6321d766250ba1e5ffe5b7ab4e2b #-}
The other mode scans a set of Haskell files for GUID pragmas and spits out
appropriate stub modules. The Haskell files are listed on the command line and
the directory in which to output the files is given on the -o option or
is the current directory by default.
An invocation in this mode might look like
./hsguid -o "$HOME/lib/hs/" *.hs
and would generate a file of the form
GUID_<guid>.hs
for each GUID pragma and place them
all in $HOME/lib/hs/
. It is recommended you keep all your guid
files in a specific directory and share them among all projects.
Ideally this functionality would be implemented with help from the compiler, but even without explicit support, we can do quite well. Here are a few caveats when using hsguid. Most deal with aliases which are relatively rare to begin with , and pretty much all can be worked around by keeping old copies of your libraries around. This is very easy to accomplish with hsguid since you can copy the library to anywhere out of the way and applications can still find it by its GUID.