And, as long as we are supporting more ADA-like import declarations,
I would like to renew my campaign for more ADA or Java like
module namespace (packages) (yes I know, this won't be in H98)
The existing module system is:
* too shallow for larger scale application development (because it is too
  easy for different developers to create modules with the same name).
* a pain when you write a package with multiple modules and each module
  has to import all the other modules in the package (except itself)

Here are the name space semantics Haskell should provide:
1. A package is a set of modules in the same directory and 
   a cluster is a set of clusters, packages, and modules in the same
   directory
2. Packages and clusters should have a globally consistent name space
3. Modules may import both other packages (all public declarations of all 
   modules in the package) or individual modules in other packages
4  Modules may (on a block level) import qualified or unqualified
5. Modules should have access to all functions in a package
   without knowing the module in which the function sas declared
6. Modules should be able to hide specific declarations from their
    own package
7. Module level exports should define visibility to other packages

I suggest the following (strawman) implementation syntax:
1. Module/package names should have a java-like import syntax e.g.
   com->numeric_quest->fun_pdf (for Jan's haskell/pdf library) and map to
   a directory structure (off of the source/lib path) of
   com/numeric-quest/fun-pdf

2. clusters and packages as functions
Generalize import.  Treat clusters, packages, and modules as functions
which take a name and return a cluster, package, module, or function.
Since we don't want all names in all paths to pollute module name space, I
suggest using the "->" operator.  e.g. 

> myFun =\x -> com->numeric_quest->fun_pdf->somePDFFunction x

Use of -> in function definitions outside or on the right of lambda
expressions tells the compiler/interpreter to resolve an import.

You run into a slight problem with -> polluting the type namespace,
but clusters and package names are functions and are therefore lower case.

> myFun::Int -> (com->numeric_quest->fun_pdf->PDFDocument)

(If you want, you can interpret the type of myFun as taking an Int and
the fun_pdf package and returning a PDFDocument i.e. linking to
fun-pdf may happen at runtime)

Import renames work like function names:
> funpdf = com->numeric_quest->fun_pdf

If you want to combine the current namespace with the namespace of another
module or package, instead of the keyword "use", you do:

> com->numeric_quest->
>  myFun = \x -> fun_pdf->somePDFFunction x -- fun_pdf is inside numeric_quest
>  myVal = pdfConstant
>  fun_pdf->                                -- downscope
>   myFun2 = \x -> anotherPDFFunction x -- anothterPDFFunction is in fun_pdf module

This should feel vaguely like using lambda expressions.

3. Accessing the current package with "package"
To import the contents of the current package use,
> package->
>  myVal = somePackageFunction 3

"package" is a special keyword to denote the current package.

4. To hide specific declarations from the surrounding package,
   declare them Private e.g.
   Private myConst=2 (or would a private section be better?)

The stuff below is more speculative and assumes a modularized Haskell
compiler/interpreter.

5. Future Proofing and Supporting Multiple Haskell Versions

Since Haskell is changing rapidly and you don't want to force library
writers to update all the time, it would be nice if the module system
insulated programmers from library changes.  (this is especially true with
the new binary lib spec from GHC/Hugs). Since, e.g. H98, Mondrian, Polyp
all evaluate to some desugared abstract haskell semantics that can be made
visible to other packages, if would be nice to provide a way of telling
the intepreter/compiler which "preprocessor" to apply.  By convention, the
first non-comment word in a module should be either "module" or the name
of the interpreter e.g.

> Haskell98 module moduleName (export1,export2) where ....
> Mondrian module moduleName (export1,export2) where
> Polyp module moduleName where 
> MySyntax module moduleName where

are the first lines of different modules which tell the 
compiler/interpreter to use the preprocessor for Haskell98, Mondrian,
Polyp, or MySyntax respectively.  

6. Foreign Language Imports (even more speculative)
Conversely, if you have a library with substantively different semantics
e.g. Clean, OCAML, DCOM, SQL, but whose semantics can find
systematic expression in the Haskell type/name system, then you might have
semantic importers of the form 

> haskellGraphics = java2Haskell "java.lang.awt"
 or
> mySchema = schemaSQL2Haskell mySQLSchema 

The first imports java graphics for use in Haskell.  The second takes a
sql schema and generates corresponding Haskell datatypes and functions.
haskellAWT and mySchema have type Package and can be used as:
> haskellGraphics ->
>  myGraphicsfunction = ...

You could also use this facility on Haskell modules to get "enhanced"
versions of Haskell modules packages e.g.

> fooFolds = meijerFoldGenerator_1_0 "foopackage"

Imports fooPackage and generates fold functions for all imported
datatypes.

This functionality requires the ability to "plug-in" import scope
resolvers and I have no idea whether this is reasonable in any existing
implementation.

-Alex-

___________________________________________________________________
S. Alexander Jacobson                   i2x Media  
1-212-697-0184 voice                    1-212-697-1427 fax









Reply via email to