Packages are the outermost constructs in BH--- all BH code must be inside packages. There should be one package per file. A BH package is a linguistic device for namespace control, and is particularly useful for programming-in-the-large. A package does not directly correspond to hardware modules. (Hardware modules correspond to BH modules, described in section 5.13)
A BH package consists of the package header, import declarations, and top level definitions. The package header indicates which names defined in this package are exported, i.e., available for import into other packages.
packageDefn ::= package packageId ( exportDecl ) where {
{ importDecl ; }
{ fixityDecl ; }
{ topDefn ; }
}
exportDecl ::= varId |typeId [ conList ]
conList ::= (..)
importDecl ::= import [ qualified ] packageId
fixityDecl ::= fixity integer varId
fixity ::= infix |infixl |infixr
packageId ::= conId
Example:
package Foo (x, y) where
-- top level definition ...
-- top level definition ...
-- top level definition ...
Here, Foo
is the name of this package, x
and y
are names exported from this package (they will be defined amongst the
top level definitions in this package), and Bar
and Glurph
are the
names of package being imported (for use in this package).
The export list is a list of identifiers, each optionally followed by
(..)
. Each identifier in the list will be visible outside the package.
If the exported identifier is the name of data
, struct
, or
interface
, then the constructors or fields of the type will be visible
only if (..)
is used. Otherwise, if you export only the name of a type
without the (..)
suffix, the type is an abstract (opaque) data type
outside the package. The list of identifiers may include identifiers
defined in the package as well as identifiers imported from other
packages.
If the keyword qualified
is present in the import declaration all the
imported entities from that package must be referred to by a qualified
name.
The fixity declaration can be used to give a precedence level to a
user-defined infix operator. The infixl
specifies a left associative
operator, infixr
a right associative operator, and infix
a
non-associative operator.
When used in any scope, a name must have an unambiguous meaning. If there is name clash for a name $x$ because it is defined in the current package and/or it is available from one or more imported packages, then the ambiguity can be resolved by using a qualified name of the form $M.x$ to refer to the version of $x$ contained in package $M$.