% Copyright The Numerical Algorithms Group Limited 1992-94. All rights reserved. % !! DO NOT MODIFY THIS FILE BY HAND !! Created by ht.awk. \texht{\setcounter{chapter}{1}}{} % Chapter 2 % \newcommand{\ugTypesTitle}{Using Types and Modes} \newcommand{\ugTypesNumber}{2.} % % ===================================================================== \begin{page}{ugTypesPage}{2. Using Types and Modes} % ===================================================================== \beginscroll In this chapter we look at the key notion of \spadgloss{type} and its generalization \spadgloss{mode}. We show that every \Language{} object has a type that determines what you can do with the object. In particular, we explain how to use types to call specific functions from particular parts of the library and how types and modes can be used to create new objects from old. We also look at \pspadtype{Record} and \pspadtype{Union} types and the special type \axiomType{Any}. Finally, we give you an idea of how \Language{} manipulates types and modes internally to resolve ambiguities. \beginmenu \menudownlink{{2.1. The Basic Idea}}{ugTypesBasicPage} \menudownlink{{2.2. Writing Types and Modes}}{ugTypesWritingPage} \menudownlink{{2.3. Declarations}}{ugTypesDeclarePage} \menudownlink{{2.4. Records}}{ugTypesRecordsPage} \menudownlink{{2.5. Unions}}{ugTypesUnionsPage} \menudownlink{{2.6. The ``Any'' Domain}}{ugTypesAnyNonePage} \menudownlink{{2.7. Conversion}}{ugTypesConvertPage} \menudownlink{{2.8. Subdomains Again}}{ugTypesSubdomainsPage} \menudownlink{{2.9. Package Calling and Target Types}}{ugTypesPkgCallPage} \menudownlink{{2.10. Resolving Types}}{ugTypesResolvePage} \menudownlink{{2.11. Exposing Domains and Packages}}{ugTypesExposePage} \menudownlink{{2.12. Commands for Snooping}}{ugAvailSnoopPage} \endmenu \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesBasicTitle}{The Basic Idea} \newcommand{\ugTypesBasicNumber}{2.1.} % % ===================================================================== \begin{page}{ugTypesBasicPage}{2.1. The Basic Idea} % ===================================================================== \beginscroll The \Language{} world deals with many kinds of objects. There are mathematical objects such as numbers and polynomials, data structure objects such as lists and arrays, and graphics objects such as points and graphic images. Functions are objects too. \Language{} organizes objects using the notion of \spadglossSee{domain of computation}{domain}, or simply \spadgloss{domain}. Each domain denotes a class of objects. The class of objects it denotes is usually given by the name of the domain: \axiomType{Integer} for the integers, \axiomType{Float} for floating-point numbers, and so on. The convention is that the first letter of a domain name is capitalized. Similarly, the domain \axiomType{Polynomial(Integer)} denotes ``polynomials with integer coefficients.'' Also, \axiomType{Matrix(Float)} denotes ``matrices with floating-point entries.'' Every basic \Language{} object belongs to a unique domain. The integer \axiom{3} belongs to the domain \axiomType{Integer} and the polynomial \axiom{x + 3} belongs to the domain \axiomType{Polynomial(Integer)}. The domain of an object is also called its \spadgloss{type}. Thus we speak of ``the type \axiomType{Integer}'' and ``the type \axiomType{Polynomial(Integer)}.'' \xtc{ After an \Language{} computation, the type is displayed toward the right-hand side of the page (or screen). }{ \spadpaste{-3} } \xtc{ Here we create a rational number but it looks like the last result. The type however tells you it is different. You cannot identify the type of an object by how \Language{} displays the object. }{ \spadpaste{-3/1} } \xtc{ When a computation produces a result of a simpler type, \Language{} leaves the type unsimplified. Thus no information is lost. }{ \spadpaste{x + 3 - x \bound{three}} } \xtc{ This seldom matters since \Language{} retracts the answer to the simpler type if it is necessary. }{ \spadpaste{factorial(\%) \free{three}} } \xtc{ When you issue a positive number, the type \axiomType{PositiveInteger} is printed. Surely, \axiom{3} also has type \axiomType{Integer}! The curious reader may now have two questions. First, is the type of an object not unique? Second, how is \axiomType{PositiveInteger} related to \axiomType{Integer}? Read on! }{ \spadpaste{3} } Any domain can be refined to a \spadgloss{subdomain} by a membership \spadgloss{predicate}.\footnote{A predicate is a function that, when applied to an object of the domain, returns either \axiom{true} or \axiom{false}.} For example, the domain \axiomType{Integer} can be refined to the subdomain \axiomType{PositiveInteger}, the set of integers \axiom{x} such that \axiom{x > 0}, by giving the \Language{} predicate \axiom{x +-> x > 0}. Similarly, \Language{} can define subdomains such as ``the subdomain of diagonal matrices,'' ``the subdomain of lists of length two,'' ``the subdomain of monic irreducible polynomials in \axiom{x},'' and so on. Trivially, any domain is a subdomain of itself. While an object belongs to a unique domain, it can belong to any number of subdomains. Any subdomain of the domain of an object can be used as the {\it type} of that object. The type of \axiom{3} is indeed both \axiomType{Integer} and \axiomType{PositiveInteger} as well as any other subdomain of integer whose predicate is satisfied, such as ``the prime integers,'' ``the odd positive integers between 3 and 17,'' and so on. \beginmenu \menudownlink{{2.1.1. Domain Constructors}}{ugTypesBasicDomainConsPage} \endmenu \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesBasicDomainConsTitle}{Domain Constructors} \newcommand{\ugTypesBasicDomainConsNumber}{2.1.1.} % % ===================================================================== \begin{page}{ugTypesBasicDomainConsPage}{2.1.1. Domain Constructors} % ===================================================================== \beginscroll In \Language{}, domains are objects. You can create them, pass them to functions, and, as we'll see later, test them for certain properties. In \Language{}, you ask for a value of a function by applying its name to a set of arguments. \xtc{ To ask for ``the factorial of 7'' you enter this expression to \Language{}. This applies the function \axiom{factorial} to the value \axiom{7} to compute the result. }{ \spadpaste{factorial(7)} } \xtc{ Enter the type \axiomType{Polynomial (Integer)} as an expression to \Language{}. This looks much like a function call as well. It is! The result is appropriately stated to be of type \axiomType{Domain}, which according to our usual convention, denotes the class of all domains. }{ \spadpaste{Polynomial(Integer)} } The most basic operation involving domains is that of building a new domain from a given one. To create the domain of ``polynomials over the integers,'' \Language{} applies the function \axiomType{Polynomial} to the domain \axiomType{Integer}. A function like \axiomType{Polynomial} is called a \spadgloss{domain constructor} or, %-% \HDindex{constructor!domain}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} more simply, a \spadgloss{constructor}. A domain constructor is a function that creates a domain. An argument to a domain constructor can be another domain or, in general, an arbitrary kind of object. \axiomType{Polynomial} takes a single domain argument while \axiomType{SquareMatrix} takes a positive integer as an argument to give its dimension and a domain argument to give the type of its components. What kinds of domains can you use as the argument to \axiomType{Polynomial} or \axiomType{SquareMatrix} or \axiomType{List}? Well, the first two are mathematical in nature. You want to be able to perform algebraic operations like \axiomOp{+} and \axiomOp{*} on polynomials and square matrices, and operations such as \axiomFun{determinant} on square matrices. So you want to allow polynomials of integers {\it and} polynomials of square matrices with complex number coefficients and, in general, anything that ``makes sense.'' At the same time, you don't want \Language{} to be able to build nonsense domains such as ``polynomials of strings!'' In contrast to algebraic structures, data structures can hold any kind of object. Operations on lists such as \axiomFunFrom{insert}{List}, \axiomFunFrom{delete}{List}, and \axiomFunFrom{concat}{List} just manipulate the list itself without changing or operating on its elements. Thus you can build \axiomType{List} over almost any datatype, including itself. \xtc{ Create a complicated algebraic domain. }{ \spadpaste{List (List (Matrix (Polynomial (Complex (Fraction (Integer))))))} } \xtc{ Try to create a meaningless domain. }{ \spadpaste{Polynomial(String)} } Evidently from our last example, \Language{} has some mechanism that tells what a constructor can use as an argument. This brings us to the notion of \spadgloss{category}. As domains are objects, they too have a domain. The domain of a domain is a category. A category is simply a type whose members are domains. A common algebraic category is \axiomType{Ring}, the class of all domains that are ``rings.'' A ring is an algebraic structure with constants \axiom{0} and \axiom{1} and operations \axiomOpFrom{+}{Ring}, \axiomOpFrom{-}{Ring}, and \axiomOpFrom{*}{Ring}. These operations are assumed ``closed'' with respect to the domain, meaning that they take two objects of the domain and produce a result object also in the domain. The operations are understood to satisfy certain ``axioms,'' certain mathematical principles providing the algebraic foundation for rings. For example, the {\it additive inverse axiom} for rings states: \centerline{{Every element \axiom{x} has an additive inverse \axiom{y} such}} \centerline{{that \axiom{x + y = 0}.}} The prototypical example of a domain that is a ring is the integers. Keep them in mind whenever we mention \axiomType{Ring}. Many algebraic domain constructors such as \axiomType{Complex}, \axiomType{Polynomial}, \axiomType{Fraction}, take rings as arguments and return rings as values. You can use the infix operator ``\axiom{has}'' \spadkey{has} to ask a domain if it belongs to a particular category. \xtc{ All numerical types are rings. Domain constructor \axiomType{Polynomial} builds ``the ring of polynomials over any other ring.'' }{ \spadpaste{Polynomial(Integer) has Ring} } \xtc{ Constructor \axiomType{List} never produces a ring. }{ \spadpaste{List(Integer) has Ring} } \xtc{ The constructor \axiomType{Matrix(R)} builds ``the domain of all matrices over the ring \axiom{R}.'' This domain is never a ring since the operations \axiomSyntax{+}, \axiomSyntax{-}, and \axiomSyntax{*} on matrices of arbitrary shapes are undefined. }{ \spadpaste{Matrix(Integer) has Ring} } \xtc{ Thus you can never build polynomials over matrices. }{ \spadpaste{Polynomial(Matrix(Integer))} } \xtc{ Use \axiomType{SquareMatrix(n,R)} instead. For any positive integer \axiom{n}, it builds ``the ring of \axiom{n} by \axiom{n} matrices over \axiom{R}.'' }{ \spadpaste{Polynomial(SquareMatrix(7,Complex(Integer)))} } Another common category is \axiomType{Field}, the class of all fields. %-% \HDindex{field}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} A field is a ring with additional operations. For example, a field has commutative multiplication and a closed operation \axiomOpFrom{/}{Field} for the division of two elements. \axiomType{Integer} is not a field since, for example, \axiom{3/2} does not have an integer result. The prototypical example of a field is the rational numbers, that is, the domain \axiomType{Fraction(Integer)}. In general, the constructor \axiomType{Fraction} takes a ring as an argument and returns a field.\footnote{Actually, the argument domain must have some additional properties so as to belong to category \axiomType{IntegralDomain}.} Other domain constructors, such as \axiomType{Complex}, build fields only if their argument domain is a field. \xtc{ The complex integers (often called the ``Gaussian integers'') do not form a field. }{ \spadpaste{Complex(Integer) has Field} } \xtc{ But fractions of complex integers do. }{ \spadpaste{Fraction(Complex(Integer)) has Field} } \xtc{ The algebraically equivalent domain of complex rational numbers is a field since domain constructor \axiomType{Complex} produces a field whenever its argument is a field. }{ \spadpaste{Complex(Fraction(Integer)) has Field} } The most basic category is \axiomType{Type}. %-% \HDexptypeindex{Type}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} It denotes the class of all domains and subdomains.\footnote{\axiomType{Type} does not denote the class of all types. The type of all categories is \axiomType{Category}. The type of \axiomType{Type} itself is undefined.} Domain constructor \axiomType{List} is able to build ``lists of elements from domain \axiom{D}'' for arbitrary \axiom{D} simply by requiring that \axiom{D} belong to category \axiomType{Type}. Now, you may ask, what exactly is a category? %-% \HDindex{category}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} Like domains, categories can be defined in the \Language{} language. A category is defined by three components: % \indent{4} \beginitems \item[1. ] a name (for example, \axiomType{Ring}), used to refer to the class of domains that the category represents; \item[2. ] a set of operations, used to refer to the operations that the domains of this class support (for example, \axiomOp{+}, \axiomOp{-}, and \axiomOp{*} for rings); and \item[3. ] an optional list of other categories that this category extends. \enditems \indent{0} % This last component is a new idea. And it is key to the design of \Language{}! Because categories can extend one another, they form hierarchies. \texht{Detailed charts showing the category hierarchies in \Language{} are displayed in the endpages of this book. There you see that all categories are extensions of \axiomType{Type} and that \axiomType{Field} is an extension of \axiomType{Ring}.}{} The operations supported by the domains of a category are called the \spadglossSee{exports}{export} of that category because these are the operations made available for system-wide use. The exports of a domain of a given category are not only the ones explicitly mentioned by the category. Since a category extends other categories, the operations of these other categories---and all categories these other categories extend---are also exported by the domains. For example, polynomial domains belong to \axiomType{PolynomialCategory}. This category explicitly mentions some twenty-nine operations on polynomials, but it extends eleven other categories (including \axiomType{Ring}). As a result, the current system has over one hundred operations on polynomials. If a domain belongs to a category that extends, say, \axiomType{Ring}, it is convenient to say that the domain exports \axiomType{Ring}. The name of the category thus provides a convenient shorthand for the list of operations exported by the category. Rather than listing operations such as \axiomOpFrom{+}{Ring} and \axiomOpFrom{*}{Ring} of \axiomType{Ring} each time they are needed, the definition of a type simply asserts that it exports category \axiomType{Ring}. The category name, however, is more than a shorthand. The name \axiomType{Ring}, in fact, implies that the operations exported by rings are required to satisfy a set of ``axioms'' associated with the name \axiomType{Ring}.\footnote{This subtle but important feature distinguishes \Language{} from other abstract datatype designs.} Why is it not correct to assume that some type is a ring if it exports all of the operations of \axiomType{Ring}? Here is why. Some languages such as {\bf APL} %-% \HDindex{APL}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} denote the \axiomType{Boolean} constants \axiom{true} and \axiom{false} by the integers \axiom{1} and \axiom{0} respectively, then use \axiomOp{+} and \axiomOp{*} to denote the logical operators \axiomFun{or} and \axiomFun{and}. But with these definitions \axiomType{Boolean} is not a ring since the additive inverse axiom is violated.\footnote{There is no inverse element \axiom{a} such that \axiom{1 + a = 0}, or, in the usual terms: \axiom{true or a = false}.} This alternative definition of \axiomType{Boolean} can be easily and correctly implemented in \Language{}, since \axiomType{Boolean} simply does not assert that it is of category \axiomType{Ring}. This prevents the system from building meaningless domains such as \axiomType{Polynomial(Boolean)} and then wrongfully applying algorithms that presume that the ring axioms hold. Enough on categories. To learn more about them, see \downlink{``\ugCategoriesTitle''}{ugCategoriesPage} in Chapter \ugCategoriesNumber\ignore{ugCategories}. We now return to our discussion of domains. Domains \spadgloss{export} a set of operations to make them available for system-wide use. \axiomType{Integer}, for example, exports the operations \axiomOpFrom{+}{Integer} and \axiomOpFrom{=}{Integer} given by the \spadglossSee{signatures}{signature} \axiomOpFrom{+}{Integer}: \spadsig{(Integer,Integer)}{Integer} and \axiomOpFrom{=}{Integer}: \spadsig{(Integer,Integer)}{Boolean}, respectively. Each of these operations takes two \axiomType{Integer} arguments. The \axiomOpFrom{+}{Integer} operation also returns an \axiomType{Integer} but \axiomOpFrom{=}{Integer} returns a \axiomType{Boolean}: \axiom{true} or \axiom{false}. The operations exported by a domain usually manipulate objects of the domain---but not always. The operations of a domain may actually take as arguments, and return as values, objects from any domain. For example, \axiomType{Fraction (Integer)} exports the operations \axiomOpFrom{/}{Fraction}: \spadsig{(Integer,Integer)}{Fraction(Integer)} and \axiomFunFrom{characteristic}{Fraction}: \spadsig{}{NonNegativeInteger}. Suppose all operations of a domain take as arguments and return as values, only objects from {\it other} domains. %-% \HDindex{package}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} This kind of domain %-% \HDindex{constructor!package}{ugTypesBasicDomainConsPage}{2.1.1.}{Domain Constructors} is what \Language{} calls a \spadgloss{package}. A package does not designate a class of objects at all. Rather, a package is just a collection of operations. Actually the bulk of the \Language{} library of algorithms consists of packages. The facilities for factorization; integration; solution of linear, polynomial, and differential equations; computation of limits; and so on, are all defined in packages. Domains needed by algorithms can be passed to a package as arguments or used by name if they are not ``variable.'' Packages are useful for defining operations that convert objects of one type to another, particularly when these types have different parameterizations. As an example, the package \axiomType{PolynomialFunction2(R,S)} defines operations that convert polynomials over a domain \axiom{R} to polynomials over \axiom{S}. To convert an object from \axiomType{Polynomial(Integer)} to \axiomType{Polynomial(Float)}, \Language{} builds the package \axiomType{PolynomialFunctions2(Integer,Float)} in order to create the required conversion function. (This happens ``behind the scenes'' for you: see \downlink{``\ugTypesConvertTitle''}{ugTypesConvertPage} in Section \ugTypesConvertNumber\ignore{ugTypesConvert} for details on how to convert objects.) \Language{} categories, domains and packages and all their contained functions are written in the \Language{} programming language and have been compiled into machine code. This is what comprises the \Language{} \spadgloss{library}. In the rest of this book we show you how to use these domains and their functions and how to write your own functions. \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingTitle}{Writing Types and Modes} \newcommand{\ugTypesWritingNumber}{2.2.} % % ===================================================================== \begin{page}{ugTypesWritingPage}{2.2. Writing Types and Modes} % ===================================================================== \beginscroll % We have already seen in \texht{the last section}{\downlink{``\ugTypesBasicTitle''}{ugTypesBasicPage} in Section \ugTypesBasicNumber\ignore{ugTypesBasic}} several examples of types. Most of these examples had either no arguments (for example, \axiomType{Integer}) or one argument (for example, \axiomType{Polynomial (Integer)}). In this section we give details about writing arbitrary types. We then define \spadglossSee{modes}{mode} and discuss how to write them. We conclude the section with a discussion on constructor abbreviations. \xtc{ When might you need to write a type or mode? You need to do so when you declare variables. }{ \spadpaste{a : PositiveInteger} } \xtc{ You need to do so when you declare functions (\downlink{``\ugTypesDeclareTitle''}{ugTypesDeclarePage} in Section \ugTypesDeclareNumber\ignore{ugTypesDeclare}), }{ \spadpaste{f : Integer -> String} } \xtc{ You need to do so when you convert an object from one type to another (\downlink{``\ugTypesConvertTitle''}{ugTypesConvertPage} in Section \ugTypesConvertNumber\ignore{ugTypesConvert}). }{ \spadpaste{factor(2 :: Complex(Integer))} } \xtc{ }{ \spadpaste{(2 = 3)\$Integer} } \xtc{ You need to do so when you give computation target type information (\downlink{``\ugTypesPkgCallTitle''}{ugTypesPkgCallPage} in Section \ugTypesPkgCallNumber\ignore{ugTypesPkgCall}). }{ \spadpaste{(2 = 3)@Boolean} } \beginmenu \menudownlink{{2.2.1. Types with No Arguments}}{ugTypesWritingZeroPage} \menudownlink{{2.2.2. Types with One Argument}}{ugTypesWritingOnePage} \menudownlink{{2.2.3. Types with More Than One Argument}}{ugTypesWritingMorePage} \menudownlink{{2.2.4. Modes}}{ugTypesWritingModesPage} \menudownlink{{2.2.5. Abbreviations}}{ugTypesWritingAbbrPage} \endmenu \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingZeroTitle}{Types with No Arguments} \newcommand{\ugTypesWritingZeroNumber}{2.2.1.} % % ===================================================================== \begin{page}{ugTypesWritingZeroPage}{2.2.1. Types with No Arguments} % ===================================================================== \beginscroll A constructor with no arguments can be written either %-% \HDindex{type!using parentheses}{ugTypesWritingZeroPage}{2.2.1.}{Types with No Arguments} with or without %-% \HDindex{parentheses!using with types}{ugTypesWritingZeroPage}{2.2.1.}{Types with No Arguments} trailing opening and closing parentheses (\axiomSyntax{()}). \texht{ \centerline{{\begin{tabular}{ccc}}} \centerline{{\axiomType{Boolean()} is the same as \axiomType{Boolean} & \quad &}} \centerline{{\axiomType{Integer()} is the same as \axiomType{Integer} }} \centerline{{\axiomType{String()} is the same as \axiomType{String} & \quad &}} \centerline{{\axiomType{Void()} is the same as \axiomType{Void} }} \centerline{{\end{tabular}}} }{ \centerline{{\axiomType{Boolean()} is the same as \axiomType{Boolean} }} \centerline{{\axiomType{Integer()} is the same as \axiomType{Integer} }} \centerline{{\axiomType{String()} is the same as \axiomType{String} }} \centerline{{\axiomType{Void()} is the same as \axiomType{Void} }} and so on. } It is customary to omit the parentheses. \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingOneTitle}{Types with One Argument} \newcommand{\ugTypesWritingOneNumber}{2.2.2.} % % ===================================================================== \begin{page}{ugTypesWritingOnePage}{2.2.2. Types with One Argument} % ===================================================================== \beginscroll A constructor with one argument can frequently be %-% \HDindex{type!using parentheses}{ugTypesWritingOnePage}{2.2.2.}{Types with One Argument} written with no %-% \HDindex{parentheses!using with types}{ugTypesWritingOnePage}{2.2.2.}{Types with One Argument} parentheses. Types nest from right to left so that \axiomType{Complex Fraction Polynomial Integer} is the same as \axiomType{Complex (Fraction (Polynomial (Integer)))}. You need to use parentheses to force the application of a constructor to the correct argument, but you need not use any more than is necessary to remove ambiguities. Here are some guidelines for using parentheses (they are possibly slightly more restrictive than they need to be). \xtc{ If the argument is an expression like \axiom{2 + 3} then you must enclose the argument in parentheses. }{ \spadpaste{e : PrimeField(2 + 3)} } % \xtc{ If the type is to be used with package calling then you must enclose the argument in parentheses. }{ \spadpaste{content(2)\$Polynomial(Integer)} } \xtc{ Alternatively, you can write the type without parentheses then enclose the whole type expression with parentheses. }{ \spadpaste{content(2)\$(Polynomial Complex Fraction Integer)} } \xtc{ If you supply computation target type information (\downlink{``\ugTypesPkgCallTitle''}{ugTypesPkgCallPage} in Section \ugTypesPkgCallNumber\ignore{ugTypesPkgCall}) then you should enclose the argument in parentheses. }{ \spadpaste{(2/3)@Fraction(Polynomial(Integer))} } % \xtc{ If the type itself has parentheses around it and we are not in the case of the first example above, then the parentheses can usually be omitted. }{ \spadpaste{(2/3)@Fraction(Polynomial Integer)} } % \xtc{ If the type is used in a declaration and the argument is a single-word type, integer or symbol, then the parentheses can usually be omitted. }{ \spadpaste{(d,f,g) : Complex Polynomial Integer} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingMoreTitle}{Types with More Than One Argument} \newcommand{\ugTypesWritingMoreNumber}{2.2.3.} % % ===================================================================== \begin{page}{ugTypesWritingMorePage}{2.2.3. Types with More Than One Argument} % ===================================================================== \beginscroll If a constructor %-% \HDindex{type!using parentheses}{ugTypesWritingMorePage}{2.2.3.}{Types with More Than One Argument} has more than %-% \HDindex{parentheses!using with types}{ugTypesWritingMorePage}{2.2.3.}{Types with More Than One Argument} one argument, you must use parentheses. Some examples are \centerline{{\axiomType{UnivariatePolynomial(x, Float)} }} \centerline{{\axiomType{MultivariatePolynomial([z,w,r], Complex Float)} }} \centerline{{\axiomType{SquareMatrix(3, Integer)} }} \centerline{{\axiomType{FactoredFunctions2(Integer,Fraction Integer)}}} \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingModesTitle}{Modes} \newcommand{\ugTypesWritingModesNumber}{2.2.4.} % % ===================================================================== \begin{page}{ugTypesWritingModesPage}{2.2.4. Modes} % ===================================================================== \beginscroll A \spadgloss{mode} is a type that possibly is a question mark (\axiomSyntax{?}) or contains one in an argument position. For example, the following are all modes. \texht{ \centerline{{\begin{tabular}{ccc}}} \centerline{{\axiomType{?} & \quad &}} \centerline{{\axiomType{Polynomial ?} }} \centerline{{\axiomType{Matrix Polynomial ?} & \quad &}} \centerline{{\axiomType{SquareMatrix(3,?)} }} \centerline{{\axiomType{Integer} & \quad &}} \centerline{{\axiomType{OneDimensionalArray(Float)}}} \centerline{{\end{tabular}}} }{ \centerline{{\axiomType{?} }} \centerline{{\axiomType{Polynomial ?} }} \centerline{{\axiomType{Matrix Polynomial ?} }} \centerline{{\axiomType{SquareMatrix(3,?)} }} \centerline{{\axiomType{Integer} }} \centerline{{\axiomType{OneDimensionalArray(Float)}}} } As is evident from these examples, a mode is a type with a part that is not specified (indicated by a question mark). Only one \axiomSyntax{?} is allowed per mode and it must appear in the most deeply nested argument that is a type. Thus \nonLibAxiomType{?(Integer)}, \nonLibAxiomType{Matrix(? (Polynomial))}, \nonLibAxiomType{SquareMatrix(?, Integer)} and \nonLibAxiomType{SquareMatrix(?, ?)} are all invalid. The question mark must take the place of a domain, not data (for example, the integer that is the dimension of a square matrix). This rules out, for example, the two \axiomType{SquareMatrix} expressions. Modes can be used for declarations (\downlink{``\ugTypesDeclareTitle''}{ugTypesDeclarePage} in Section \ugTypesDeclareNumber\ignore{ugTypesDeclare}) and conversions (\downlink{``\ugTypesConvertTitle''}{ugTypesConvertPage} in Section \ugTypesConvertNumber\ignore{ugTypesConvert}). However, you cannot use a mode for package calling or giving target type information. \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesWritingAbbrTitle}{Abbreviations} \newcommand{\ugTypesWritingAbbrNumber}{2.2.5.} % % ===================================================================== \begin{page}{ugTypesWritingAbbrPage}{2.2.5. Abbreviations} % ===================================================================== \beginscroll Every constructor has an abbreviation that %-% \HDindex{abbreviation!constructor}{ugTypesWritingAbbrPage}{2.2.5.}{Abbreviations} you can freely %-% \HDindex{constructor!abbreviation}{ugTypesWritingAbbrPage}{2.2.5.}{Abbreviations} substitute for the constructor name. In some cases, the abbreviation is nothing more than the capitalized version of the constructor name. \beginImportant Aside from allowing types to be written more concisely, abbreviations are used by \Language{} to name various system files for constructors (such as library filenames, test input files and example files). Here are some common abbreviations. \texht{}{\table{ {\axiomType{COMPLEX} abbreviates \axiomType{Complex} } {\axiomType{DFLOAT} abbreviates \axiomType{DoubleFloat} } {\axiomType{EXPR} abbreviates \axiomType{Expression} } {\axiomType{FLOAT} abbreviates \axiomType{Float} } {\axiomType{FRAC} abbreviates \axiomType{Fraction} } {\axiomType{INT} abbreviates \axiomType{Integer} } {\axiomType{MATRIX} abbreviates \axiomType{Matrix} } {\axiomType{NNI} abbreviates \axiomType{NonNegativeInteger} } {\axiomType{PI} abbreviates \axiomType{PositiveInteger} } {\axiomType{POLY} abbreviates \axiomType{Polynomial} } {\axiomType{STRING} abbreviates \axiomType{String} } {\axiomType{UP} abbreviates \axiomType{UnivariatePolynomial} } }} \endImportant You can combine both full constructor names and abbreviations in a type expression. Here are some types using abbreviations. \centerline{{\axiomType{POLY INT} is the same as \axiomType{Polynomial(INT)} }} \centerline{{\axiomType{POLY(Integer)} is the same as \axiomType{Polynomial(Integer)} }} \centerline{{\axiomType{POLY(Integer)} is the same as \axiomType{Polynomial(INT)} }} \centerline{{\axiomType{FRAC(COMPLEX(INT))} is the same as \axiomType{Fraction Complex Integer} }} \centerline{{\axiomType{FRAC(COMPLEX(INT))} is the same as \axiomType{FRAC(Complex Integer)} }} There are several ways of finding the names of constructors and their abbreviations. For a specific constructor, use \spadcmd{)abbreviation query}. %-% \HDsyscmdindex{abbreviation}{ugTypesWritingAbbrPage}{2.2.5.}{Abbreviations} You can also use the \spadcmd{)what} system command to see the names and abbreviations of constructors. %-% \HDsyscmdindex{what}{ugTypesWritingAbbrPage}{2.2.5.}{Abbreviations} For more information about \spadcmd{)what}, see \downlink{``\ugSysCmdwhatTitle''}{ugSysCmdwhatPage} in Section \ugSysCmdwhatNumber\ignore{ugSysCmdwhat}. \xtc{ \spadcmd{)abbreviation query} can be abbreviated (no pun intended) to \spadcmd{)abb q}. }{ \spadpaste{)abb q Integer} } \xtc{ The \spadcmd{)abbreviation query} command lists the constructor name if you give the abbreviation. Issue \spadcmd{)abb q} if you want to see the names and abbreviations of all \Language{} constructors. }{ \spadpaste{)abb q DMP} } \xtc{ Issue this to see all packages whose names contain the string ``ode''. %-% \HDsyscmdindex{what packages}{ugTypesWritingAbbrPage}{2.2.5.}{Abbreviations} }{ \spadpaste{)what packages ode} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesDeclareTitle}{Declarations} \newcommand{\ugTypesDeclareNumber}{2.3.} % % ===================================================================== \begin{page}{ugTypesDeclarePage}{2.3. Declarations} % ===================================================================== \beginscroll % A \spadgloss{declaration} is an expression used to restrict the type of values that can be assigned to variables. A colon (\axiomSyntax{:}) is always used after a variable or list of variables to be declared. \beginImportant For a single variable, the syntax for declaration is \centerline{{{\it variableName \axiom{:} typeOrMode}}} For multiple variables, the syntax is \centerline{{{\tt (\subscriptIt{variableName}{1}, \subscriptIt{variableName}{2}, \ldots \subscriptIt{variableName}{N}): {\it typeOrMode}}}} \endImportant You can always combine a declaration with an assignment. When you do, it is equivalent to first giving a declaration statement, then giving an assignment. For more information on assignment, see \downlink{``\ugIntroAssignTitle''}{ugIntroAssignPage} in Section \ugIntroAssignNumber\ignore{ugIntroAssign} and \downlink{``\ugLangAssignTitle''}{ugLangAssignPage} in Section \ugLangAssignNumber\ignore{ugLangAssign}. To see how to declare your own functions, see \downlink{``\ugUserDeclareTitle''}{ugUserDeclarePage} in Section \ugUserDeclareNumber\ignore{ugUserDeclare}. \xtc{ This declares one variable to have a type. }{ \spadpaste{a : Integer \bound{a}} } \xtc{ This declares several variables to have a type. }{ \spadpaste{(b,c) : Integer \bound{b c}} } \xtc{ \axiom{a, b} and \axiom{c} can only hold integer values. }{ \spadpaste{a := 45 \free{a}} } \xtc{ If a value cannot be converted to a declared type, an error message is displayed. }{ \spadpaste{b := 4/5 \free{b}} } \xtc{ This declares a variable with a mode. }{ \spadpaste{n : Complex ? \bound{n}} } \xtc{ This declares several variables with a mode. }{ \spadpaste{(p,q,r) : Matrix Polynomial ? \bound{p q r}} } \xtc{ This complex object has integer real and imaginary parts. }{ \spadpaste{n := -36 + 9 * \%i \free{n}} } \xtc{ This complex object has fractional symbolic real and imaginary parts. }{ \spadpaste{n := complex(4/(x + y),y/x) \free{n}} } \xtc{ This matrix has entries that are polynomials with integer coefficients. }{ \spadpaste{p := [[1,2],[3,4],[5,6]] \free{p}} } \xtc{ This matrix has a single entry that is a polynomial with rational number coefficients. }{ \spadpaste{q := [[x - 2/3]] \free{q}} } \xtc{ This matrix has entries that are polynomials with complex integer coefficients. }{ \spadpaste{r := [[1-\%i*x,7*y+4*\%i]] \free{r}} } % \xtc{ Note the difference between this and the next example. This is a complex object with polynomial real and imaginary parts. }{ \spadpaste{f : COMPLEX POLY ? := (x + y*\%i)**2} } \xtc{ This is a polynomial with complex integer coefficients. The objects are convertible from one to the other. See \downlink{``\ugTypesConvertTitle''}{ugTypesConvertPage} in Section \ugTypesConvertNumber\ignore{ugTypesConvert} for more information. }{ \spadpaste{g : POLY COMPLEX ? := (x + y*\%i)**2} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesRecordsTitle}{Records} \newcommand{\ugTypesRecordsNumber}{2.4.} % % ===================================================================== \begin{page}{ugTypesRecordsPage}{2.4. Records} % ===================================================================== \beginscroll % A \pspadtype{Record} is an object composed of one or more other objects, %-% \HDindex{Record@\protect\nonLibAxiomType{Record}}{ugTypesRecordsPage}{2.4.}{Records} each of which is referenced %-% \HDindex{selector!record}{ugTypesRecordsPage}{2.4.}{Records} with %-% \HDindex{record!selector}{ugTypesRecordsPage}{2.4.}{Records} a \spadgloss{selector}. Components can all belong to the same type or each can have a different type. \beginImportant The syntax for writing a \pspadtype{Record} type is \centerline{{{\tt Record(\subscriptIt{selector}{1}:\subscriptIt{type}{1}, \subscriptIt{selector}{2}:\subscriptIt{type}{2}, \ldots, \subscriptIt{selector}{N}:\subscriptIt{type}{N})}}} You must be careful if a selector has the same name as a variable in the workspace. If this occurs, precede the selector name by a single %-% \HDindex{quote}{ugTypesRecordsPage}{2.4.}{Records} quote. \endImportant Record components are implicitly ordered. All the components of a record can be set at once by assigning the record a bracketed \spadgloss{tuple} of values of the proper length (for example, \axiom{r : Record(a: Integer, b: String) := [1, "two"]}). To access a component of a record \axiom{r}, write the name \axiom{r}, followed by a period, followed by a selector. % \xtc{ The object returned by this computation is a record with two components: a \axiom{quotient} part and a \axiom{remainder} part. }{ \spadpaste{u := divide(5,2) \bound{u}} } % \xtc{ This is the quotient part. }{ \spadpaste{u.quotient \free{u}} } \xtc{ This is the remainder part. }{ \spadpaste{u.remainder \free{u}} } % \xtc{ You can use selector expressions on the left-hand side of an assignment to change destructively the components of a record. }{ \spadpaste{u.quotient := 8978 \free{u}\bound{u1}} } \xtc{ The selected component \axiom{quotient} has the value \axiom{8978}, which is what is returned by the assignment. Check that the value of \axiom{u} was modified. }{ \spadpaste{u \free{u}\free{u1}} } \xtc{ Selectors are evaluated. Thus you can use variables that evaluate to selectors instead of the selectors themselves. }{ \spadpaste{s := 'quotient \bound{s}} } \xtc{ Be careful! A selector could have the same name as a variable in the workspace. If this occurs, precede the selector name by a single quote, as in \axiom{u.'quotient}. %-% \HDindex{selector!quoting}{ugTypesRecordsPage}{2.4.}{Records} }{ \spadpaste{divide(5,2).s \free{s}} } \xtc{ Here we declare that the value of \axiom{bd} has two components: a string, to be accessed via \axiom{name}, and an integer, to be accessed via \axiom{birthdayMonth}. }{ \spadpaste{bd : Record(name : String, birthdayMonth : Integer) \bound{bddec}} } \xtc{ You must initially set the value of the entire \pspadtype{Record} at once. }{ \spadpaste{bd := ["Judith", 3] \free{bddec}\bound{bd}} } \xtc{ Once set, you can change any of the individual components. }{ \spadpaste{bd.name := "Katie" \free{bd}} } \xtc{ Records may be nested and the selector names can be shared at different levels. }{ \spadpaste{r : Record(a : Record(b: Integer, c: Integer), b: Integer) \bound{rdec}} } \xtc{ The record \axiom{r} has a \axiom{b} selector at two different levels. Here is an initial value for \axiom{r}. }{ \spadpaste{r := [[1,2],3] \bound{r}\free{rdec}} } \xtc{ This extracts the \axiom{b} component from the \axiom{a} component of \axiom{r}. }{ \spadpaste{r.a.b \free{r}} } \xtc{ This extracts the \axiom{b} component from \axiom{r}. }{ \spadpaste{r.b \free{r}} } % \xtc{ You can also use spaces or parentheses to refer to \pspadtype{Record} components. This is the same as \axiom{r.a}. }{ \spadpaste{r(a) \free{r}} } \xtc{ This is the same as \axiom{r.b}. }{ \spadpaste{r b \free{r}} } \xtc{ This is the same as \axiom{r.b := 10}. }{ \spadpaste{r(b) := 10 \free{r}\bound{r1}} } \xtc{ Look at \axiom{r} to make sure it was modified. }{ \spadpaste{r \free{r1}} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesUnionsTitle}{Unions} \newcommand{\ugTypesUnionsNumber}{2.5.} % % ===================================================================== \begin{page}{ugTypesUnionsPage}{2.5. Unions} % ===================================================================== \beginscroll % Type \pspadtype{Union} is used for objects that can be of any of a specific finite set of types. %-% \HDindex{Union@\protect\nonLibAxiomType{Union}}{ugTypesUnionsPage}{2.5.}{Unions} Two versions of unions are available, one with selectors (like records) and one without. %-% \HDindex{union}{ugTypesUnionsPage}{2.5.}{Unions} \beginmenu \menudownlink{{2.5.1. Unions Without Selectors}}{ugTypesUnionsWOSelPage} \menudownlink{{2.5.2. Unions With Selectors}}{ugTypesUnionsWSelPage} \endmenu \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesUnionsWOSelTitle}{Unions Without Selectors} \newcommand{\ugTypesUnionsWOSelNumber}{2.5.1.} % % ===================================================================== \begin{page}{ugTypesUnionsWOSelPage}{2.5.1. Unions Without Selectors} % ===================================================================== \beginscroll The declaration \axiom{x : Union(Integer, String, Float)} states that \axiom{x} can have values that are integers, strings or ``big'' floats. If, for example, the \pspadtype{Union} object is an integer, the object is said to belong to the \axiomType{Integer} {\it branch} of the \pspadtype{Union}.\footnote{ Note that we are being a bit careless with the language here. Technically, the type of \axiom{x} is always \pspadtype{Union(Integer, String, Float)}. If it belongs to the \axiomType{Integer} branch, \axiom{x} may be converted to an object of type \axiomType{Integer}.} \beginImportant The syntax for writing a \pspadtype{Union} type without selectors is \centerline{{{\tt Union(\subscriptIt{type}{1}, \subscriptIt{type}{2}, \ldots, \subscriptIt{type}{N})}}} The types in a union without selectors must be distinct. \endImportant It is possible to create unions like \pspadtype{Union(Integer, PositiveInteger)} but they are difficult to work with because of the overlap in the branch types. See below for the rules \Language{} uses for converting something into a union object. The \axiom{case} infix \spadkey{case} operator returns a \axiomType{Boolean} and can be used to determine the branch in which an object lies. \xtc{ This function displays a message stating in which branch of the \pspadtype{Union} the object (defined as \axiom{x} above) lies. }{ \begin{spadsrc}[\bound{sayBranch}] sayBranch(x : Union(Integer,String,Float)) : Void == output x case Integer => "Integer branch" x case String => "String branch" "Float branch" \end{spadsrc} } % \xtc{ This tries \userfun{sayBranch} with an integer. }{ \spadpaste{sayBranch 1 \free{sayBranch}} } \xtc{ This tries \userfun{sayBranch} with a string. }{ \spadpaste{sayBranch "hello" \free{sayBranch}} } \xtc{ This tries \userfun{sayBranch} with a floating-point number. }{ \spadpaste{sayBranch 2.718281828 \free{sayBranch}} } % There are two things of interest about this particular example to which we would like to draw your attention. \indent{4} \beginitems % \item[1. ] \Language{} normally converts a result to the target value before passing it to the function. If we left the declaration information out of this function definition then the \axiom{sayBranch} call would have been attempted with an \axiomType{Integer} rather than a \pspadtype{Union}, and an error would have resulted. % \item[2. ] The types in a \pspadtype{Union} are searched in the order given. So if the type were given as \noindent {\small\axiom{sayBranch(x: Union(String,Integer,Float,Any)): Void}} \noindent then the result would have been ``String branch'' because there is a conversion from \axiomType{Integer} to \axiomType{String}. \enditems \indent{0} Sometimes \pspadtype{Union} types can have extremely long names. \Language{} therefore abbreviates the names of unions by printing the type of the branch first within the \pspadtype{Union} and then eliding the remaining types with an ellipsis (\axiomSyntax{...}). \xtc{ Here the \axiomType{Integer} branch is displayed first. Use \axiomSyntax{::} to create a \pspadtype{Union} object from an object. }{ \spadpaste{78 :: Union(Integer,String)} } \xtc{ Here the \axiomType{String} branch is displayed first. }{ \spadpaste{s := "string" :: Union(Integer,String) \bound{s}} } \xtc{ Use \axiom{typeOf} to see the full and actual \pspadtype{Union} type. \spadkey{typeOf} }{ \spadpaste{typeOf s} } \xtc{ A common operation that returns a union is \axiomFunFrom{exquo}{Integer} which returns the ``exact quotient'' if the quotient is exact,... }{ \spadpaste{three := exquo(6,2) \bound{three}} } \xtc{ and \axiom{"failed"} if the quotient is not exact. }{ \spadpaste{exquo(5,2)} } \xtc{ A union with a \axiom{"failed"} is frequently used to indicate the failure or lack of applicability of an object. As another example, assign an integer a variable \axiom{r} declared to be a rational number. }{ \spadpaste{r: FRAC INT := 3 \bound{r}\bound{rdec}} } \xtc{ The operation \axiomFunFrom{retractIfCan}{Fraction} tries to retract the fraction to the underlying domain \axiomType{Integer}. It produces a union object. Here it succeeds. }{ \spadpaste{retractIfCan(r) \free{r}} } \xtc{ Assign it a rational number. }{ \spadpaste{r := 3/2 \bound{r1}\free{rdec}} } \xtc{ Here the retraction fails. }{ \spadpaste{retractIfCan(r) \free{r1}} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesUnionsWSelTitle}{Unions With Selectors} \newcommand{\ugTypesUnionsWSelNumber}{2.5.2.} % % ===================================================================== \begin{page}{ugTypesUnionsWSelPage}{2.5.2. Unions With Selectors} % ===================================================================== \beginscroll Like records (\downlink{``\ugTypesRecordsTitle''}{ugTypesRecordsPage} in Section \ugTypesRecordsNumber\ignore{ugTypesRecords}), you can write \pspadtype{Union} types %-% \HDindex{selector!union}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} with selectors. %-% \HDindex{union!selector}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} \beginImportant The syntax for writing a \pspadtype{Union} type with selectors is \centerline{{{\tt Union(\subscriptIt{selector}{1}:\subscriptIt{type}{1}, \subscriptIt{selector}{2}:\subscriptIt{type}{2}, \ldots, \subscriptIt{selector}{N}:\subscriptIt{type}{N})}}} You must be careful if a selector has the same name as a variable in the workspace. If this occurs, precede the selector name by a single %-% \HDindex{quote}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} quote. %-% \HDindex{selector!quoting}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} It is an error to use a selector that does not correspond to the branch of the \pspadtype{Union} in which the element actually lies. \endImportant Be sure to understand the difference between records and unions with selectors. %-% \HDindex{union!difference from record}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} Records can have more than one component and the selectors are used to refer to the components. %-% \HDindex{record!difference from union}{ugTypesUnionsWSelPage}{2.5.2.}{Unions With Selectors} Unions always have one component but the type of that one component can vary. An object of type \pspadtype{Record(a: Integer, b: Float, c: String)} contains an integer {\it and} a float {\it and} a string. An object of type \pspadtype{Union(a: Integer, b: Float, c: String)} contains an integer {\it or} a float {\it or} a string. Here is a version of the \userfun{sayBranch} function (cf. \downlink{``\ugTypesUnionsWOSelTitle''}{ugTypesUnionsWOSelPage} in Section \ugTypesUnionsWOSelNumber\ignore{ugTypesUnionsWOSel}) that works with a union with selectors. It displays a message stating in which branch of the \pspadtype{Union} the object lies. \begin{verbatim} sayBranch(x:Union(i:Integer,s:String,f:Float)):Void== output x case i => "Integer branch" x case s => "String branch" "Float branch" \end{verbatim} Note that \axiom{case} uses the selector name as its right-hand argument. \spadkey{case} If you accidentally use the branch type on the right-hand side of \axiom{case}, \axiom{false} will be returned. \xtc{ Declare variable \axiom{u} to have a union type with selectors. }{ \spadpaste{u : Union(i : Integer, s : String) \bound{undec}} } \xtc{ Give an initial value to \axiom{u}. }{ \spadpaste{u := "good morning" \bound{u}\free{undec}} } \xtc{ Use \axiom{case} to determine in which branch of a \pspadtype{Union} an object lies. }{ \spadpaste{u case i \free{u}} } \xtc{ }{ \spadpaste{u case s \free{u}} } \xtc{ To access the element in a particular branch, use the selector. }{ \spadpaste{u.s \free{u}} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesAnyNoneTitle}{The ``Any'' Domain} \newcommand{\ugTypesAnyNoneNumber}{2.6.} % % ===================================================================== \begin{page}{ugTypesAnyNonePage}{2.6. The ``Any'' Domain} % ===================================================================== \beginscroll With the exception of objects of type \pspadtype{Record}, all \Language{} data structures are homogenous, that is, they hold objects all of the same type. %-% \HDexptypeindex{Any}{ugTypesAnyNonePage}{2.6.}{The ``Any'' Domain} If you need to get around this, you can use type \axiomType{Any}. Using \axiomType{Any}, for example, you can create lists whose elements are integers, rational numbers, strings, and even other lists. \xtc{ Declare \axiom{u} to have type \axiomType{Any}. }{ \spadpaste{u: Any\bound{uany}} } \xtc{ Assign a list of mixed type values to \axiom{u} }{ \spadpaste{u := [1, 7.2, 3/2, x**2, "wally"]\free{uany}\bound{u}} } \xtc{ When we ask for the elements, \Language{} displays these types. }{ \spadpaste{u.1 \free{u}} } \xtc{ Actually, these objects belong to \axiomType{Any} but \Language{} automatically converts them to their natural types for you. }{ \spadpaste{u.3 \free{u}} } \xtc{ Since type \axiomType{Any} can be anything, it can only belong to type \axiomType{Type}. Therefore it cannot be used in algebraic domains. }{ \spadpaste{v : Matrix(Any)} } Perhaps you are wondering how \Language{} internally represents objects of type \axiomType{Any}. An object of type \axiomType{Any} consists not only a data part representing its normal value, but also a type part (a {\it badge}) giving %-% \HDindex{badge}{ugTypesAnyNonePage}{2.6.}{The ``Any'' Domain} its type. For example, the value \axiom{1} of type \axiomType{PositiveInteger} as an object of type \axiomType{Any} internally looks like \axiom{[1,\axiomType{PositiveInteger()}]}. %When should you use \axiomType{Any} instead of a \pspadtype{Union} type? %Can you plan ahead? %For a \pspadtype{Union}, you must know in advance exactly which types you %are %\index{union!vs. Any@{vs. \protect\nonLibAxiomType{Any}}} %going to allow. %For \axiomType{Any}, anything that comes along can be accommodated. \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesConvertTitle}{Conversion} \newcommand{\ugTypesConvertNumber}{2.7.} % % ===================================================================== \begin{page}{ugTypesConvertPage}{2.7. Conversion} % ===================================================================== \beginscroll % \beginImportant \spadglossSee{Conversion}{conversion} is the process of changing an object of one type into an object of another type. The syntax for conversion is: \centerline{{{\it object} {\tt ::} {\it newType}}} \endImportant \xtc{ By default, \axiom{3} has the type \axiomType{PositiveInteger}. }{ \spadpaste{3} } \xtc{ We can change this into an object of type \axiomType{Fraction Integer} by using \axiomSyntax{::}. }{ \spadpaste{3 :: Fraction Integer} } A \spadgloss{coercion} is a special kind of conversion that \Language{} is allowed to do automatically when you enter an expression. Coercions are usually somewhat safer than more general conversions. The \Language{} library contains operations called \axiomFun{coerce} and \axiomFun{convert}. Only the \axiomFun{coerce} operations can be used by the interpreter to change an object into an object of another type unless you explicitly use a \axiomSyntax{::}. By now you will be quite familiar with what types and modes look like. It is useful to think of a type or mode as a pattern for what you want the result to be. \xtc{ Let's start with a square matrix of polynomials with complex rational number coefficients. %-% \HDexptypeindex{SquareMatrix}{ugTypesConvertPage}{2.7.}{Conversion} }{ \spadpaste{m : SquareMatrix(2,POLY COMPLEX FRAC INT) \bound{mdec}} } \xtc{ }{ \spadpaste{m := matrix [[x-3/4*\%i,z*y**2+1/2],[3/7*\%i*y**4 - x,12-\%i*9/5]] \bound{m}\free{mdec}} } \xtc{ We first want to interchange the \axiomType{Complex} and \axiomType{Fraction} layers. We do the conversion by doing the interchange in the type expression. }{ \spadpaste{m1 := m :: SquareMatrix(2,POLY FRAC COMPLEX INT) \free{m}\bound{m1}} } \xtc{ Interchange the \axiomType{Polynomial} and the \axiomType{Fraction} levels. }{ \spadpaste{m2 := m1 :: SquareMatrix(2,FRAC POLY COMPLEX INT) \free{m1}\bound{m2}} } \xtc{ Interchange the \axiomType{Polynomial} and the \axiomType{Complex} levels. }{ \spadpaste{m3 := m2 :: SquareMatrix(2,FRAC COMPLEX POLY INT) \free{m2}\bound{m3}} } All the entries have changed types, although in comparing the last two results only the entry in the lower left corner looks different. We did all the intermediate steps to show you what \Language{} can do. \xtc{ In fact, we could have combined all these into one conversion. }{ \spadpaste{m :: SquareMatrix(2,FRAC COMPLEX POLY INT) \free{m}} } There are times when \Language{} is not be able to do the conversion in one step. You may need to break up the transformation into several conversions in order to get an object of the desired type. We cannot move either \axiomType{Fraction} or \axiomType{Complex} above (or to the left of, depending on how you look at it) \axiomType{SquareMatrix} because each of these levels requires that its argument type have commutative multiplication, whereas \axiomType{SquareMatrix} does not.\footnote{\axiomType{Fraction} requires that its argument belong to the category \axiomType{IntegralDomain} and %-% \HDindex{category}{ugTypesConvertPage}{2.7.}{Conversion} \axiomType{Complex} requires that its argument belong to \axiomType{CommutativeRing}. See \downlink{``\ugTypesBasicTitle''}{ugTypesBasicPage} in Section \ugTypesBasicNumber\ignore{ugTypesBasic} for a brief discussion of categories.} The \axiomType{Integer} level did not move anywhere because it does not allow any arguments. We also did not move the \axiomType{SquareMatrix} part anywhere, but we could have. \xtc{ Recall that \axiom{m} looks like this. }{ \spadpaste{m \free{m}} } \xtc{ If we want a polynomial with matrix coefficients rather than a matrix with polynomial entries, we can just do the conversion. }{ \spadpaste{m :: POLY SquareMatrix(2,COMPLEX FRAC INT) \free{m}} } \xtc{ We have not yet used modes for any conversions. Modes are a great shorthand for indicating the type of the object you want. Instead of using the long type expression in the last example, we could have simply said this. }{ \spadpaste{m :: POLY ? \free{m}} } \xtc{ We can also indicate more structure if we want the entries of the matrices to be fractions. }{ \spadpaste{m :: POLY SquareMatrix(2,FRAC ?) \free{m}} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesSubdomainsTitle}{Subdomains Again} \newcommand{\ugTypesSubdomainsNumber}{2.8.} % % ===================================================================== \begin{page}{ugTypesSubdomainsPage}{2.8. Subdomains Again} % ===================================================================== \beginscroll A \spadgloss{subdomain} \axiom{S} of a domain \axiom{D} is a domain consisting of \indent{4} \beginitems \item[1. ] those elements of \axiom{D} that satisfy some \spadgloss{predicate} (that is, a test that returns \axiom{true} or \axiom{false}) and \item[2. ] a subset of the operations of \axiom{D}. \enditems \indent{0} Every domain is a subdomain of itself, trivially satisfying the membership test: \axiom{true}. Currently, there are only two system-defined subdomains in \Language{} that receive substantial use. \axiomType{PositiveInteger} and \axiomType{NonNegativeInteger} are subdomains of \axiomType{Integer}. An element \axiom{x} of \axiomType{NonNegativeInteger} is an integer that is greater than or equal to zero, that is, satisfies \axiom{x >= 0.} An element \axiom{x} of \axiomType{PositiveInteger} is a nonnegative integer that is, in fact, greater than zero, that is, satisfies \axiom{x > 0.} Not all operations from \axiomType{Integer} are available for these subdomains. For example, negation and subtraction are not provided since the subdomains are not closed under those operations. When you use an integer in an expression, \Language{} assigns to it the type that is the most specific subdomain whose predicate is satisfied. \xtc{ This is a positive integer. }{ \spadpaste{5} } \xtc{ This is a nonnegative integer. }{ \spadpaste{0} } \xtc{ This is neither of the above. }{ \spadpaste{-5} } \xtc{ Furthermore, unless you are assigning an integer to a declared variable or using a conversion, any integer result has as type the most specific subdomain. }{ \spadpaste{(-2) - (-3)} } \xtc{ }{ \spadpaste{0 :: Integer} } \xtc{ }{ \spadpaste{x : NonNegativeInteger := 5} } When necessary, \Language{} converts an integer object into one belonging to a less specific subdomain. For example, in \axiom{3-2}, the arguments to \axiomOpFrom{-}{Integer} are both elements of \axiomType{PositiveInteger}, but this type does not provide a subtraction operation. Neither does \axiomType{NonNegativeInteger}, so \axiom{3} and \axiom{2} are viewed as elements of \axiomType{Integer}, where their difference can be calculated. The result is \axiom{1}, which \Language{} then automatically assigns the type \axiomType{PositiveInteger}. \xtc{ Certain operations are very sensitive to the subdomains to which their arguments belong. This is an element of \axiomType{PositiveInteger}. }{ \spadpaste{2 ** 2} } \xtc{ This is an element of \axiomType{Fraction Integer}. }{ \spadpaste{2 ** (-2)} } \xtc{ It makes sense then that this is a list of elements of \axiomType{PositiveInteger}. }{ \spadpaste{[10**i for i in 2..5]} } What should the type of \axiom{[10**(i-1) for i in 2..5]} be? On one hand, \axiom{i-1} is always an integer greater than zero as \axiom{i} ranges from \axiom{2} to \axiom{5} and so \axiom{10**i} is also always a positive integer. On the other, \axiom{i-1} is a very simple function of \axiom{i}. \Language{} does not try to analyze every such function over the index's range of values to determine whether it is always positive or nowhere negative. For an arbitrary \Language{} function, this analysis is not possible. \xtc{ So, to be consistent no such analysis is done and we get this. }{ \spadpaste{[10**(i-1) for i in 2..5]} } \xtc{ To get a list of elements of \axiomType{PositiveInteger} instead, you have two choices. You can use a conversion. }{ \spadpaste{[10**((i-1) :: PI) for i in 2..5]} } \xtc{ Or you can use \axiom{pretend}. \spadkey{pretend} }{ \spadpaste{[10**((i-1) pretend PI) for i in 2..5]} } The operation \axiom{pretend} is used to defeat the \Language{} type system. The expression \axiom{object pretend D} means ``make a new object (without copying) of type \axiom{D} from \axiom{object}.'' If \axiom{object} were an integer and you told \Language{} to pretend it was a list, you would probably see a message about a fatal error being caught and memory possibly being damaged. Lists do not have the same internal representation as integers! You use \axiom{pretend} at your peril. %-% \HDindex{peril}{ugTypesSubdomainsPage}{2.8.}{Subdomains Again} \xtc{ Use \axiom{pretend} with great care! \Language{} trusts you that the value is of the specified type. }{ \spadpaste{(2/3) pretend Complex Integer} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesPkgCallTitle}{Package Calling and Target Types} \newcommand{\ugTypesPkgCallNumber}{2.9.} % % ===================================================================== \begin{page}{ugTypesPkgCallPage}{2.9. Package Calling and Target Types} % ===================================================================== \beginscroll \Language{} works hard to figure out what you mean by an expression without your having to qualify it with type information. Nevertheless, there are times when you need to help it along by providing hints (or even orders!) to get \Language{} to do what you want. We saw in \downlink{``\ugTypesDeclareTitle''}{ugTypesDeclarePage} in Section \ugTypesDeclareNumber\ignore{ugTypesDeclare} that declarations using types and modes control the type of the results produced. For example, we can either produce a complex object with polynomial real and imaginary parts or a polynomial with complex integer coefficients, depending on the declaration. \spadglossSee{Package calling}{package call} is how you tell \Language{} to use a particular function from a particular part of the library. \xtc{ Use the \axiomOpFrom{/}{Fraction} from \axiomType{Fraction Integer} to create a fraction of two integers. }{ \spadpaste{2/3} } \xtc{ If we wanted a floating point number, we can say ``use the \axiomOpFrom{/}{Float} in \axiomType{Float}.'' }{ \spadpaste{(2/3)\$Float} } \xtc{ Perhaps we actually wanted a fraction of complex integers. }{ \spadpaste{(2/3)\$Fraction(Complex Integer)} } In each case, \Language{} used the indicated operations, sometimes first needing to convert the two integers into objects of an appropriate type. In these examples, \axiomOpFrom{/}{Fraction} is written as an infix operator. \beginImportant To use package calling with an infix operator, use the following syntax: \centerline{{{\tt ( \subscriptIt{arg}{1} {\it op} \subscriptIt{arg}{1} )\${\it type} }}} \endImportant We used, for example, \axiom{(2/3)\$Float}. The expression \axiom{2 + 3 + 4} is equivalent to \axiom{(2+3) + 4.} Therefore in the expression \axiom{(2 + 3 + 4)\$Float} the second \axiomOp{+} comes from the \axiomType{Float} domain. Can you guess whether the first \axiomOp{+} comes from \axiomType{Integer} or \axiomType{Float}?\footnote{\axiomType{Float}, because the package call causes \Language{} to convert \axiom{(2 + 3)} and \axiom{4} to type \axiomType{Float}. Before the sum is converted, it is given a target type (see below) of \axiomType{Float} by \Language{} and then evaluated. The target type causes the \axiomOp{+} from \axiomType{Float} to be used.} \beginImportant For an operator written before its arguments, you must use parentheses around the arguments (even if there is only one), and follow the closing parenthesis by a \axiomSyntax{\$} and then the type. \centerline{{{\tt {\it fun} ( \subscriptIt{arg}{1}, \subscriptIt{arg}{1}, \ldots, \subscriptIt{arg}{N} )\${\it type}}}} \endImportant For example, to call the ``minimum'' function from \axiomType{DoubleFloat} on two integers, you could write \axiom{min(4,89)\$DoubleFloat}. Another use of package calling is to tell \Language{} to use a library function rather than a function you defined. We discuss this in \downlink{``\ugUserUseTitle''}{ugUserUsePage} in Section \ugUserUseNumber\ignore{ugUserUse}. Sometimes rather than specifying where an operation comes from, you just want to say what type the result should be. We say that you provide %-% \HDindex{type!target}{ugTypesPkgCallPage}{2.9.}{Package Calling and Target Types} a \spadglossSee{target type}{target} for the expression. %-% \HDindex{target type}{ugTypesPkgCallPage}{2.9.}{Package Calling and Target Types} Instead of using a \axiomSyntax{\$}, use a \axiomSyntax{@} to specify the requested target type. Otherwise, the syntax is the same. Note that giving a target type is not the same as explicitly doing a conversion. The first says ``try to pick operations so that the result has such-and-such a type.'' The second says ``compute the result and then convert to an object of such-and-such a type.'' \xtc{ Sometimes it makes sense, as in this expression, to say ``choose the operations in this expression so that the final result is a \axiomType{Float}.'' }{ \spadpaste{(2/3)@Float} } Here we used \axiomSyntax{@} to say that the target type of the left-hand side was \axiomType{Float}. In this simple case, there was no real difference between using \axiomSyntax{\$} and \axiomSyntax{@}. You can see the difference if you try the following. \xtc{ This says to try to choose \axiomOp{+} so that the result is a string. \Language{} cannot do this. }{ \spadpaste{(2 + 3)@String} } \xtc{ This says to get the \axiomOp{+} from \axiomType{String} and apply it to the two integers. \Language{} also cannot do this because there is no \axiomOp{+} exported by \axiomType{String}. }{ \spadpaste{(2 + 3)\$String} } (By the way, the operation \axiomFunFrom{concat}{String} or juxtaposition is used to concatenate two strings.) %-% \HDexptypeindex{String}{ugTypesPkgCallPage}{2.9.}{Package Calling and Target Types} When we have more than one operation in an expression, the difference is even more evident. The following two expressions show that \Language{} uses the target type to create different objects. The \axiomOp{+}, \axiomOp{*} and \axiomOp{**} operations are all chosen so that an object of the correct final type is created. \xtc{ This says that the operations should be chosen so that the result is a \axiomType{Complex} object. }{ \spadpaste{((x + y * \%i)**2)@(Complex Polynomial Integer)} } \xtc{ This says that the operations should be chosen so that the result is a \axiomType{Polynomial} object. }{ \spadpaste{((x + y * \%i)**2)@(Polynomial Complex Integer)} } \xtc{ What do you think might happen if we left off all target type and package call information in this last example? }{ \spadpaste{(x + y * \%i)**2 \bound{prevC}} } \xtc{ We can convert it to \axiomType{Complex} as an afterthought. But this is more work than just saying making what we want in the first place. }{ \spadpaste{\% :: Complex ? \free{prevC}} } Finally, another use of package calling is to qualify fully an operation that is passed as an argument to a function. \xtc{ Start with a small matrix of integers. }{ \spadpaste{h := matrix [[8,6],[-4,9]] \bound{h}} } % \xtc{ We want to produce a new matrix that has for entries the multiplicative inverses of the entries of \axiom{h}. One way to do this is by calling \axiomFunFrom{map}{MatrixCategoryFunctions2} with the \axiomFunFrom{inv}{Fraction} function from \axiomType{Fraction (Integer)}. }{ \spadpaste{map(inv\$Fraction(Integer),h) \free{h}} } \xtc{ We could have been a bit less verbose and used abbreviations. }{ \spadpaste{map(inv\$FRAC(INT),h) \free{h}\bound{h1}} } % \xtc{ As it turns out, \Language{} is smart enough to know what we mean anyway. We can just say this. }{ \spadpaste{map(inv,h) \free{h}} } \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesResolveTitle}{Resolving Types} \newcommand{\ugTypesResolveNumber}{2.10.} % % ===================================================================== \begin{page}{ugTypesResolvePage}{2.10. Resolving Types} % ===================================================================== \beginscroll In this section we briefly describe an internal process by which %-% \HDindex{resolve}{ugTypesResolvePage}{2.10.}{Resolving Types} \Language{} determines a type to which two objects of possibly different types can be converted. We do this to give you further insight into how \Language{} takes your input, analyzes it, and produces a result. What happens when you enter \axiom{x + 1} to \Language{}? Let's look at what you get from the two terms of this expression. \xtc{ This is a symbolic object whose type indicates the name. }{ \spadpaste{x} } \xtc{ This is a positive integer. }{ \spadpaste{1} } There are no operations in \axiomType{PositiveInteger} that add positive integers to objects of type \axiomType{Variable(x)} nor are there any in \axiomType{Variable(x)}. Before it can add the two parts, \Language{} must come up with a common type to which both \axiom{x} and \axiom{1} can be converted. We say that \Language{} must {\it resolve} the two types into a common type. In this example, the common type is \axiomType{Polynomial(Integer)}. \xtc{ Once this is determined, both parts are converted into polynomials, and the addition operation from \axiomType{Polynomial(Integer)} is used to get the answer. }{ \spadpaste{x + 1} } \xtc{ \Language{} can always resolve two types: if nothing resembling the original types can be found, then \axiomType{Any} is be used. %-% \HDexptypeindex{Any}{ugTypesResolvePage}{2.10.}{Resolving Types} This is fine and useful in some cases. }{ \spadpaste{["string",3.14159]} } \xtc{ In other cases objects of type \axiomType{Any} can't be used by the operations you specified. }{ \spadpaste{"string" + 3.14159} } Although this example was contrived, your expressions may need to be qualified slightly to help \Language{} resolve the types involved. You may need to declare a few variables, do some package calling, provide some target type information or do some explicit conversions. We suggest that you just enter the expression you want evaluated and see what \Language{} does. We think you will be impressed with its ability to ``do what I mean.'' If \Language{} is still being obtuse, give it some hints. As you work with \Language{}, you will learn where it needs a little help to analyze quickly and perform your computations. \endscroll \autobuttons \end{page} % % \newcommand{\ugTypesExposeTitle}{Exposing Domains and Packages} \newcommand{\ugTypesExposeNumber}{2.11.} % % ===================================================================== \begin{page}{ugTypesExposePage}{2.11. Exposing Domains and Packages} % ===================================================================== \beginscroll In this section we discuss how \Language{} makes some operations available to you while hiding others that are meant to be used by developers or only in rare cases. If you are a new user of \Language{}, it is likely that everything you need is available by default and you may want to skip over this section on first reading. Every %-% \HDindex{constructor!exposed}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} domain and package in the \Language{} library %-% \HDindex{constructor!hidden}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} is %-% \HDindex{exposed!constructor}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} either \spadglossSee{exposed}{expose} (meaning that you can use its operations without doing anything special) or it is {\it hidden} (meaning you have to either package call (see \downlink{``\ugTypesPkgCallTitle''}{ugTypesPkgCallPage} in Section \ugTypesPkgCallNumber\ignore{ugTypesPkgCall}) the operations it contains or explicitly expose it to use the operations). The initial exposure status for a constructor is set in the file {\bf exposed.lsp} (see the {\it Installer's Note} %-% \HDindex{exposed.lsp @{\bf exposed.lsp}}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} for \Language{} %-% \HDindex{file!exposed.lsp @{\bf exposed.lsp}}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} if you need to know the location of this file). Constructors are collected together in %-% \HDindex{group!exposure}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} {\it exposure groups}. %-% \HDindex{exposure!group}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} Categories are all in the exposure group ``categories'' and the bulk of the basic set of packages and domains that are exposed are in the exposure group ``basic.'' Here is an abbreviated sample of the file (without the Lisp parentheses): \begin{verbatim} basic AlgebraicNumber AN AlgebraGivenByStructuralConstants ALGSC Any ANY AnyFunctions1 ANY1 BinaryExpansion BINARY Boolean BOOLEAN CardinalNumber CARD CartesianTensor CARTEN Character CHAR CharacterClass CCLASS CliffordAlgebra CLIF Color COLOR Complex COMPLEX ContinuedFraction CONTFRAC DecimalExpansion DECIMAL ... \end{verbatim} \begin{verbatim} categories AbelianGroup ABELGRP AbelianMonoid ABELMON AbelianMonoidRing AMR AbelianSemiGroup ABELSG Aggregate AGG Algebra ALGEBRA AlgebraicallyClosedField ACF AlgebraicallyClosedFunctionSpace ACFS ArcHyperbolicFunctionCategory AHYP ... \end{verbatim} For each constructor in a group, the full name and the abbreviation is given. There are other groups in {\bf exposed.lsp} but initially only the constructors in exposure groups ``basic'' ``categories'' ``naglink'' and ``anna'' are exposed. As an interactive user of \Language{}, you do not need to modify this file. Instead, use \spadcmd{)set expose} to expose, hide or query the exposure status of an individual constructor or exposure group. %-% \HDsyscmdindex{set expose}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} The reason for having exposure groups is to be able to expose or hide multiple constructors with a single command. For example, you might group together into exposure group ``quantum'' a number of domains and packages useful for quantum mechanical computations. These probably should not be available to every user, but you want an easy way to make the whole collection visible to \Language{} when it is looking for operations to apply. If you wanted to hide all the basic constructors available by default, you would issue \spadcmd{)set expose drop group basic}. %-% \HDsyscmdindex{set expose drop group} We do not recommend that you do this.{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} If, however, you discover that you have hidden all the basic constructors, you should issue \spadcmd{)set expose add group basic} to restore your default environment. %-% \HDsyscmdindex{set expose add group}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} It is more likely that you would want to expose or hide individual constructors. In \downlink{``\ugUserTriangleTitle''}{ugUserTrianglePage} in Section \ugUserTriangleNumber\ignore{ugUserTriangle} we use several operations from \axiomType{OutputForm}, a domain usually hidden. To avoid package calling every operation from \axiomType{OutputForm}, we expose the domain and let \Language{} conclude that those operations should be used. Use \spadcmd{)set expose add constructor} and \spadcmd{)set expose drop constructor} to expose and hide a constructor, respectively. %-% \HDsyscmdindex{set expose drop constructor}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} You should use the constructor name, not the abbreviation. The \spadcmd{)set expose} command guides you through these options. %-% \HDsyscmdindex{set expose add constructor}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} If you expose a previously hidden constructor, \Language{} exhibits new behavior (that was your intention) though you might not expect the results that you get. \axiomType{OutputForm} is, in fact, one of the worst offenders in this regard. %-% \HDexptypeindex{OutputForm}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} This domain is meant to be used by other domains for creating a structure that \Language{} knows how to display. It has functions like \axiomOpFrom{+}{OutputForm} that form output representations rather than do mathematical calculations. Because of the order in which \Language{} looks at constructors when it is deciding what operation to apply, \axiomType{OutputForm} might be used instead of what you expect. \xtc{ This is a polynomial. }{ \spadpaste{x + x} } \xtc{ Expose \axiomType{OutputForm}. }{ \spadpaste{)set expose add constructor OutputForm \bound{setexposeadd}} } \xtc{ This is what we get when \axiomType{OutputForm} is automatically available. }{ \spadpaste{x + x \free{setexposeadd}} } \xtc{ Hide \axiomType{OutputForm} so we don't run into problems with any later examples! }{ \spadpaste{)set expose drop constructor OutputForm \bound{setexposedrop}} } Finally, exposure is done on a frame-by-frame basis. A \spadgloss{frame} (see \downlink{``\ugSysCmdframeTitle''}{ugSysCmdframePage} in Section \ugSysCmdframeNumber\ignore{ugSysCmdframe}) %-% \HDindex{frame!exposure and}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} is one of possibly several logical \Language{} workspaces within a physical one, each having its own environment (for example, variables and function definitions). If you have several \Language{} workspace windows on your screen, they are all different frames, automatically created for you by \HyperName{}. Frames can be manually created, made active and destroyed by the \spadcmd{)frame} system command. %-% \HDsyscmdindex{frame}{ugTypesExposePage}{2.11.}{Exposing Domains and Packages} They do not share exposure information, so you need to use \spadcmd{)set expose} in each one to add or drop constructors from view. \endscroll \autobuttons \end{page} % % \newcommand{\ugAvailSnoopTitle}{Commands for Snooping} \newcommand{\ugAvailSnoopNumber}{2.12.} % % ===================================================================== \begin{page}{ugAvailSnoopPage}{2.12. Commands for Snooping} % ===================================================================== \beginscroll To conclude this chapter, we introduce you to some system commands that you can use for getting more information about domains, packages, categories, and operations. The most powerful \Language{} facility for getting information about constructors and operations is the \Browse{} component of \HyperName{}. This is discussed in \downlink{``\ugBrowseTitle''}{ugBrowsePage} in Chapter \ugBrowseNumber\ignore{ugBrowse}. Use the \spadsys{)what} system command to see lists of system objects whose name contain a particular substring (uppercase or lowercase is not significant). %-% \HDsyscmdindex{what}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} \xtc{ Issue this to see a list of all operations with ``{\tt complex}'' in their names. %-% \HDsyscmdindex{what operation}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} }{ \spadpaste{)what operation complex} } \xtc{ If you want to see all domains with ``{\tt matrix}'' in their names, issue this. %-% \HDsyscmdindex{what domain}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} }{ \spadpaste{)what domain matrix} } \xtc{ Similarly, if you wish to see all packages whose names contain ``{\tt gauss}'', enter this. %-% \HDsyscmdindex{what packages}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} }{ \spadpaste{)what package gauss} } \xtc{ This command shows all the operations that \axiomType{Any} provides. Wherever \axiomSyntax{\$} appears, it means ``\axiomType{Any}''. %-% \HDsyscmdindex{show}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} }{ \spadpaste{)show Any} } \xtc{ This displays all operations with the name \axiomFun{complex}. %-% \HDsyscmdindex{display operation}{ugAvailSnoopPage}{2.12.}{Commands for Snooping} }{ \spadpaste{)display operation complex} } Let's analyze this output. \xtc{ First we find out what some of the abbreviations mean. }{ \spadpaste{)abbreviation query COMPCAT} } \xtc{ }{ \spadpaste{)abbreviation query COMRING} } So if \axiom{D1} is a commutative ring (such as the integers or floats) and \axiom{D} belongs to \axiomType{ComplexCategory D1}, then there is an operation called \axiomFun{complex} that takes two elements of \axiom{D1} and creates an element of \axiom{D}. The primary example of a constructor implementing domains belonging to \axiomType{ComplexCategory} is \axiomType{Complex}. See \downlink{`Complex'}{ComplexXmpPage}\ignore{Complex} for more information on that and see \downlink{``\ugUserDeclareTitle''}{ugUserDeclarePage} in Section \ugUserDeclareNumber\ignore{ugUserDeclare} for more information on function types. \endscroll \autobuttons \end{page} %