Axiom has the Axiom interpreter for interaction with the user and the Axiom compiler for building library modules. Axiom TypesTypes are one of the most important concepts in Axiom. Like Modula 2, PASCAL, FORTRAN, and Ada, the programming language emphasizes strict type-checking. Unlike these languages, types in Axiom are dynamic objects: they are created at run-time in response to user commands. The Axiom interactive language is oriented towards ease-of-use. The Axiom interpreter uses type-inferencing to deduce the type of an object from user input. Type declarations can generally be omitted for common types in the interactive language. The Axiom compiler language (version 1 of the language is called SPAD, version 2 of the language is called Aldor) on the other hand is based on strong static types that must be explicitly specified by the programmer. Type Inference in the Axiom InterpreterConsider axiom (1+2)/3
Type: Fraction Integer
It is sort of interesting, isn't it, that Axiom insists on calling "1" a fraction just because of the way it was calculated? There is a way to say that you want the answer as an integer. Of course this isn't always possible: axiom (1/3)::Integer But for this example it is: axiom ((1+2)/3)::Integer
Type: Integer
Axiom is very strict with types (meaning: that it must be
completely unambiguous where each operation takes place).
The division of 1+2 by 3 takes place in axiom ((1+2)/3)::Polynomial Integer
Type: Polynomial Integer
axiom ((1+2)/3)::SquareMatrix(1,Integer)
Type: SquareMatrix?(1,Integer)
axiom ((1+2)/3)::SquareMatrix(3,Integer)
Type: SquareMatrix?(3,Integer)
axiom ((1+2)/3)::SquareMatrix(3, Polynomial Complex Integer)
Type: SquareMatrix?(3,Polynomial Complex Integer)
Types of Objects, Domains, and CategoriesIn Axiom the concept of "Type" is universally applied at all levels. From the Axiom Book: Appendix B Glossary
From the Axiom Book: Technical Introduction Every Axiom object is an instance of some domain. That
domain is also called the type of the object. Thus the
Domains are defined by Axiom by programs of the form:
Name(Parameters): JoinCategorys
with Exports == Extends
add Rep == RepDomain
Implementation
The
Fraction(S: IntegralDomain): QuotientFieldCategory S with
if S has canonical and S has GcdDomain
and S has canonicalUnitNormal
then canonical
== LocalAlgebra(S, S, S) add
Rep:= Record(num:S, den:S)
coerce(d:S):% == [d,1]
zero?(x:%) == zero? x.num
Thus the type of We also say that the domain Fractions are represented as the domain In Axiom domains and subdomains are themselves objects that have types. The type of a domain or subdomain is called a category. Categories are described by programs of the form:
Name(...): Category == JoinCategorys
with Exports
add Imports
Implementation
The type of every category is the distinguished symbol
For example:
QuotientFieldCategory(S: IntegralDomain): Category ==
Join(Field, Algebra S, RetractableTo S, FullyEvalableOver S,
DifferentialExtension S, FullyLinearlyExplicitRingOver S,
Patternable S, FullyPatternMatchable S) with
_/ : (S, S) -> %
++ d1 / d2 returns the fraction d1 divided by d2.
numer : % -> S
++ numer(x) returns the numerator of the fraction x.
denom : % -> S
...
if S has PolynomialFactorizationExplicit then
PolynomialFactorizationExplicit
add
import MatrixCommonDenominator(S, %)
numerator(x) == numer(x)::%
denominator(x) == denom(x) ::%
...
Categories say nothing about representation. Domains, which are instances of category types, specify representations. See also Rep And Per. Categories form hierarchies (technically, directed-acyclic
graphs). A simplified hierarchical world of algebraic
categories is shown below. At the top of this world is
SetCategory +---- Ring ---- IntegralDomain ---- Field
|
+---- Finite ---+
| \
+---- OrderedSet -----+ OrderedFinite
Figure 1. A simplified category hierarchy.
Confusion of Type and Domain The most basic category is Another example. Enter the type axiom Polynomial(Integer)
Type: Domain
But note well that Ref: Axoim Book "Chapter 2 Using Types and Modes". Overloading and Dependent TypesMany Axiom operations have the same name but different types and these types can be dependent on other types. For example axiom )display operation differentiate We can see how the interpreter resolves the type: [14] (D,D1) -> D from D if D has PDRING D1 and D1 has SETCAT in the following example axiom )set message bottomup on
Type: Expression Integer
Notice that axiom EXPR INT has PDRING SYMBOL
Type: Boolean
axiom SYMBOL has SETCAT
Type: Boolean
Embedding Axiom categories in Axiom domains. --Bill Page, Wed, 28 Sep 2005 21:50:23 -0500 reply In light of the above definitions of Type in Axiom, it
would seem that the type of
axiom I:=Integer
Type: Domain
which Axiom prints as Issue report #209 however shows that perhaps it would be useful to flatten Axiom's two-level object model of categories and domains by embedding Categories into the domain called Domain. This would allow convenient things like evaluating the expression: (Integer,Float) as type As #209 reports, Axiom internally generates a call to the
function
interp/bootfuns.lisp.pamphlet:(def-boot-val |$Domain| '(|Domain|)
interp/br-con.boot.pamphlet: is [[h,:.],:t] and MEMBER(h,'(Domain SubDomain))
interp/clammed.boot.pamphlet: form in '((Mode) (Domain) (SubDomain (Domain))) =
interp/g-cndata.boot.pamphlet: domain in '((Mode) (Domain) (SubDomain (Doma
interp/i-analy.boot.pamphlet: if ( oo = "%" ) or ( oo = "Domain" ) or ( domainF
interp/i-coerce.boot.pamphlet: t1 in '((Mode) (Domain) (SubDomain (Domain))) =>
interp/i-funsel.boot.pamphlet: MEMBER('(SubDomain (Domain)),types1) => NIL
interp/i-output.boot.pamphlet: categoryForm? domain or domain in '((Mode) (Domain) (SubDomain (Domain))) =>
interp/i-spec1.boot.pamphlet: saeTypeSynonymValue := objNew(sae,'(Domain))
interp/i-spec1.boot.pamphlet: objMode triple = '(Domain) => triple
interp/i-spec1.boot.pamphlet: objMode(val) in '((Domain) (SubDomain (Domain))) =>
interp/i-spec2.boot.pamphlet: else if categoryForm?(type) then '(SubDomain (Domain))
interp/i-spec2.boot.pamphlet: type in '((Mode) (Domain)) => '(SubDomain (Domain))
interp/parse.boot.pamphlet: and m in '((Mode) (Domain) (SubDomain (Domain))) => D
interp/setq.lisp.pamphlet: CAPSULE |Union| |Record| |SubDomain| |Mapping| |Enumeration| |Domain| |Mode|))
interp/setq.lisp.pamphlet:(SETQ |$Domain| '(|Domain|))
interp/sys-pkg.lisp.pamphlet: BOOT::YIELD BOOT::|Polynomial| BOOT::|$Domain| BOOT::STRINGPAD
interp/trace.boot.pamphlet: (objMode value in '((Mode) (Domain) (SubDomain (Domain)))) =>
However in searching for use and meaning of the domain In
Entry : Domain := Record(symtab:SymbolTable, _
returnType:FSTU, _
argList:List Symbol)
For details see SandBox Domains And Types. So apparently at least in 1992, such a domain might have existed in Axiom. Oddly (or perhaps as we might expect :) compiling this code in the current version of Axiom produces some error messages:
Semantic Errors:
[1] Domain is not a known type
[2] void is not a known type
yet the compile does apparently successfully complete. But does it work? |

