## The PolyML.NameSpace structure

The PolyML.NameSpace structure contains functions associated with a name-space, a collection of values, types, structures, functors, signatures and infix settings. It is used primarily in connection with the compiler.

In the Standard ML language there are separate classes of identifiers for values, type constructors, structures, signatures and functors. In addition infix status is essentially another identifier class since infix status and priority can be set for an identifier whether or not there is actually a function with that name. Value identifiers include datatype and exception constructors as well as identifiers bound with val or fun bindings. Name-spaces are ways of holding and managing collections of identifiers. Nothing in the NameSpace structure assumes a particular implementation of a name-space; it is more of an interface than an implementation.

    structure NameSpace:
        sig
            structure Functors:
              sig
                val code = fn: functorVal -> CodeTree.codetree
                type functorVal
                val name = fn: functorVal -> string
                val print = fn: functorVal * int * nameSpace option -> pretty
                val properties = fn: functorVal -> ptProperties list
              end
            structure Infixes:
              sig
                type fixity
                val name = fn: fixity -> string
                val print = fn: fixity -> pretty
              end
            structure Signatures:
              sig
                val name = fn: signatureVal -> string
                val print = fn: signatureVal * int * nameSpace option -> pretty
                val properties = fn: signatureVal -> ptProperties list
                type signatureVal
              end
            structure Structures:
              sig
                val code = fn: structureVal -> CodeTree.codetree
                val contents = fn: structureVal -> nameSpace
                val name = fn: structureVal -> string
                val print = fn: structureVal * int * nameSpace option -> pretty
                val properties = fn: structureVal -> ptProperties list
                type structureVal
              end
            structure TypeConstrs:
              sig
                val name = fn: typeConstr -> string
                val print = fn: typeConstr * int * nameSpace option -> pretty
                val properties = fn: typeConstr -> ptProperties list
                type typeConstr
              end
            structure Values:
              sig
                val code = fn: value -> CodeTree.codetree
                val isConstructor = fn: value -> bool
                val isException = fn: value -> bool
                val name = fn: value -> string
                val print = fn: value * int -> pretty
                val printType = fn:
                   typeExpression * int * nameSpace option -> pretty
                val printWithType = fn: value * int * nameSpace option -> pretty
                val properties = fn: value -> ptProperties list
                type typeExpression
                val typeof = fn: value -> typeExpression
                type value
              end
        type nameSpace =
               {allFix: unit -> (string * Infixes.fixity) list,
                 allFunct: unit -> (string * Functors.functorVal) list,
                 allSig: unit -> (string * Signatures.signatureVal) list,
                 allStruct: unit -> (string * Structures.structureVal) list,
                 allType: unit -> (string * TypeConstrs.typeConstr) list,
                 allVal: unit -> (string * Values.value) list,
                 enterFix: string * Infixes.fixity -> unit,
                 enterFunct: string * Functors.functorVal -> unit,
                 enterSig: string * Signatures.signatureVal -> unit,
                 enterStruct: string * Structures.structureVal -> unit,
                 enterType: string * TypeConstrs.typeConstr -> unit,
                 enterVal: string * Values.value -> unit,
                 lookupFix: string -> Infixes.fixity option,
                 lookupFunct: string -> Functors.functorVal option,
                 lookupSig: string -> Signatures.signatureVal option,
                 lookupStruct: string -> Structures.structureVal option,
                 lookupType: string -> TypeConstrs.typeConstr option,
                 lookupVal: string -> Values.value option}
        end

    val globalNameSpace: nameSpace

    type nameSpace =
               {allFix: unit -> (string * Infixes.fixity) list,
                 allFunct: unit -> (string * Functors.functorVal) list,
                 allSig: unit -> (string * Signatures.signatureVal) list,
                 allStruct: unit -> (string * Structures.structureVal) list,
                 allType: unit -> (string * TypeConstrs.typeConstr) list,
                 allVal: unit -> (string * Values.value) list,
                 enterFix: string * Infixes.fixity -> unit,
                 enterFunct: string * Functors.functorVal -> unit,
                 enterSig: string * Signatures.signatureVal -> unit,
                 enterStruct: string * Structures.structureVal -> unit,
                 enterType: string * TypeConstrs.typeConstr -> unit,
                 enterVal: string * Values.value -> unit,
                 lookupFix: string -> Infixes.fixity option,
                 lookupFunct: string -> Functors.functorVal option,
                 lookupSig: string -> Signatures.signatureVal option,
                 lookupStruct: string -> Structures.structureVal option,
                 lookupType: string -> TypeConstrs.typeConstr option,
                 lookupVal: string -> Values.value option}

The nameSpace type is a record of functions. For each class of identifier there is a lookup function that takes a string and returns an option type, an enter function that takes a string name and adds a values to the table and an "all" function that returns a list of all the identifiers of that class. It is important to note that the nameSpace type does not imply any particular implementation, it is simply an interface. Typically, it will be implemented in terms of one or more hash-tables but it is perfectly possible to implement something more complex. For example, PolyML.make, is implemented by passing to the compiler a name-space that has a side-effect of checking, and if necessary recompiling, a file when called to look-up a structure, functor or signature.

    val globalNameSpace: nameSpace

globalNameSpace is the default name-space. The interactive top-level, the use function and PolyML.make, all use this.

    type valueVal
    type typeVal
    type fixityVal
    type functorVal
    type signatureVal
    type structureVal

Values of these types are the data structures used to represent the different kind of identifiers. Values of type valueVal are used to hold information about value identifiers, typeVal is used for type constructors, fixityVal for infix status, functorVal for functors, signatureVal for signatures and structureVal for structures. There are no constructors available to create values of these types; the only way these value can be created is by compiling ML source code.

    type typeExpression

typeExpression is used to represent the type of a value. This is not really part of a name-space but is included here, along with displayTypeExpression as a convenience. Values of this type are returned as PTtype nodes in the parse-tree.

    val displayVal: valueVal * int * nameSpace -> pretty

The displayVal function returns a text representation of the value as a pretty structure. The structure returned is similar to way values are printed at the top level and include both their value and their type. The int argument controls the depth when printing complex values. The nameSpace argument is used to assist in displaying appropriate type constructors in the type.