Based on the Aldor presentation by Stephen Watt: http://www.aldor.org/docs/reports/ukqcd-2000/intro1-ukqcd00.pdf and http://www.aldor.org/docs/HTML/chap2.html
Doubling integers
(1) -> <aldor> #include "axiom" double(n: Integer): Integer == n + n</aldor>
Compiling FriCAS source code from file /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8999780659057009231-25px001.as using Aldor compiler and options -O -Fasy -Fao -Flsp -lfricas -Mno-ALDOR_W_WillObsolete -DFriCAS -Y $FRICAS/algebra -I $FRICAS/algebra Use the system command )set compiler args to change these options. "/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8999780659057009231-25px001.as",line 1: #include "axiom" ^ [L1 C1] #1 (Error) Could not open file `axiom'.
The )library system command was not called after compilation.
double(3)
There are no exposed library operations named double but there is one unexposed operation with that name. Use HyperDoc Browse or issue )display op double to learn more about the available operation.
Cannot find a definition or applicable library operation named double with argument type(s) PositiveInteger
Perhaps you should use "@" to indicate the required return type,or "$" to specify which version of the function you need.
The first program is one which doubles integers. This program illustrates a number of things:
Square roots
#include "axiom"
Compiling FriCAS source code from file /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/3174503116170322985-25px003.as using Aldor compiler and options -O -Fasy -Fao -Flsp -lfricas -Mno-ALDOR_W_WillObsolete -DFriCAS -Y $FRICAS/algebra -I $FRICAS/algebra Use the system command )set compiler args to change these options. "/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/3174503116170322985-25px003.as",line 1: #include "axiom" ^ [L1 C1] #1 (Error) Could not open file `axiom'.
The )library system command was not called after compilation.
miniSqrt(10.0)
There are no library operations named miniSqrt Use HyperDoc Browse or issue )what op miniSqrt to learn if there is any operation containing " miniSqrt " in its name.
Cannot find a definition or applicable library operation named miniSqrt with argument type(s) Float
Perhaps you should use "@" to indicate the required return type,or "$" to specify which version of the function you need.
Our second program illustrates several more aspects of the language:
-- and continue to the end of the line.macros) may be defined using ==>. The lineDF ==> DoubleFloat?;
causes DF to be replaced by DoubleFloat wherever it is used.
:=.r is local to the function 'miniSqrt': it will not be seen from outside it. Variables may be made local to a function by a local declaration or, as in this case, implicitly, by assignment.r contains double precision floating point values. Since this may be inferred from the program, it is not necessary to provide a type declaration.A loop and output
#include "axiom"
factorial(n: Integer): Integer == {
p := 1;
for i in 1..n repeat p := p * i;
p
}
Compiling FriCAS source code from file /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8840088320957572233-25px005.as using Aldor compiler and options -O -Fasy -Fao -Flsp -lfricas -Mno-ALDOR_W_WillObsolete -DFriCAS -Y $FRICAS/algebra -I $FRICAS/algebra Use the system command )set compiler args to change these options. "/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8840088320957572233-25px005.as",line 1: #include "axiom" ^ [L1 C1] #1 (Error) Could not open file `axiom'.
The )library system command was not called after compilation.
output("factorial 10 = ", factorial 10)
factorial 10 = 3628800
The third program has a loop and produces some output. Things to notice about this program are:
: Integer suffice to make the exports from Integer visible within the factorial function. This gives meaning to 1, '* and ..'.These declarations do not, however, cause the the exports from Integer to be visible at the top-level of the file, outside the function factorial. This conservative behaviour turns out to be quite desirable when writing large programs, since adding a new function to a working program will not pollute the name space of the program into which it is inserted.
output is a operator."factorial 10 =" is a String constant.factorial and 10 come from.factorial 10. No parentheses are needed here because the function has only a single argument. If the function took two arguments, e.g. 5, 5, or if the argument were a more complicated expression, e.g. 5+5, then parentheses would be required to force the desired grouping.#include "aldor" but will not work when using #include "axiom". (In the AXIOM library, output is done by coercion to type OutputForm?). This one is not compatible with Axiom
#include "axiom"
MiniList(S: BasicType): LinearAggregate(S) == add { Rep == Union(nil: Pointer,rec: Record(first: S, rest: %));
import from Rep,SingleInteger;
local cons (s:S,l:%):% == per(union [s, l]); local first(l: %): S == rep(l).rec.first; local rest (l: %): % == rep(l).rec.rest;
empty (): % == per(union nil); empty?(l: %):Boolean == rep(l) case nil; sample: % == empty();
[t: Tuple S]: % == { l := empty(); for i in length t..1 by -1 repeat l := cons(element(t,i), l); l } [g: Generator S]: % == { r := empty(); for s in g repeat r := cons(s, r); l := empty(); for s in r repeat l := cons(s, l); l } generator(l: %): Generator S == generate { while not empty? l repeat { yield first l; l := rest l } } apply(l: %, i: SingleInteger): S == { while not empty? l and i > 1 repeat (l, i) := (rest l, i-1); empty? l or i ~= 1 => error "No such element"; first l } (l1: %) = (l2: %): Boolean == { while not empty? l1 and not empty? l2 repeat { if first l1 ~= first l2 then return false; (l1, l2) := (rest l1, rest l2) } empty? l1 and empty? l2 } (out: TextWriter) << (l: %): TextWriter == { empty? l => out << "[]"; out << "[" << first l; for s in rest l repeat out << ", " << s; out << "]" } }
Compiling FriCAS source code from file /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8737543771828864454-25px007.as using Aldor compiler and options -O -Fasy -Fao -Flsp -lfricas -Mno-ALDOR_W_WillObsolete -DFriCAS -Y $FRICAS/algebra -I $FRICAS/algebra Use the system command )set compiler args to change these options. "/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/8737543771828864454-25px007.as",line 1: #include "axiom" ^ [L1 C1] #1 (Error) Could not open file `axiom'.
The )library system command was not called after compilation.
Click above to see errors.
A few points will help in understanding this program:
add expression, itself containing several function definitions. It is these internal functions of an add function which provide the means to manipulate values belonging to the resulting types (such as MiniList?(Integer) in this case).Record, Pointer, element, etc. Some of these, such as Pointer, are made visible by the #include line, while others, such as element, are made visible by declaring values to belong to particular types. The names which have meanings in aldor are detailed in chapter 25 and chapter 26.
=), an output function (<<), and a few other operations. Since S is declared to be a BasicType?, the implementation of MiniList? can use the = and << from S in the definitions of MiniList?'s own operations.bracket to form new values, a test function called empty?, and so on. MiniList?(S) provides a LinearAggregate?(S), so it must supply all these operations. Users of MiniList?(S) will be able to rely on these operations being available.add expression defines a type Rep (specific to MiniList). This is how values of the type being defined are really represented. The fact that they are represented this way is not visible outside the add expression.%. In any add expression, the name % refers to the type under construction. For now, % can be thought of as a shorthand for MiniList(S).per and rep in this program. These are conversions which allow a data value to be regarded in is public guise, as a member of %, or by its private representation as a member of Rep.
rep: % -> Repper: Rep -> % These can be remembered by types they produce: rep produces a value in Rep, the representation, and per produces a value in %, percent.
local. This means they will be private to the add, and consequently will not be available to users of MiniList?.For example:
[t: Tuple S]: % == ... [g: Generator S]: % == ... (l1: %) = (l2: %): Boolean == ... (out: TextWriter) << (l: %): TextWriter == ...
In general, the left-hand sides of function definitions in Aldor look like function calls with added type declarations. Some names have infix syntax, for instance, = and << above. These are nevertheless just names and, aside from the grouping, behave in exactly the same way as other names. The special syntactic properties of names may be avoided by enclosing them in parentheses. Other special syntactic forms are really just a nice way to write certain function calls. The form '[a,b,c]?' is competely equivalent to the call bracket(a,b,c).
With this explanation, we see that the defining forms above are equivalent to the following, more orthodox forms:
bracket(t: Tuple S): % == ... bracket(g: Generator S): % == ... (=) (l1: %, l2: %): Boolean == ... (<<)(out: TextWriter, l: %): TextWriter == ...
The use of the type Generator S will be explained in chapter 9.
generator illustrates how a type can define its own traversal method, which allows the new type to decide how its component values should be obtained, say for use in a loop. Such a definition utilises the function generate, in conjuction with 'yield': each time a yield is encountered, generate makes the given value available to the caller and then suspends itself. This technique is described more fully in section 9.3. When the next value is needed, the generator resumes where it left off. Since MiniList?(S) provides a generator function for MiniLists?, it is possible to use them in a for loop. For example, in the output function <<, we see the line:
for s in rest l repeat out << ", " << s;
Here rest l is traversed by the generator to obtain values for s.
Questions
Pointer in Axiom?#include "axiom"
macro I == Integer; main():String == { import from I,Float; U == Union(Integer, Float); import from U; i: I := 2; s: Float := 1.5; ui: U := union i; us: U := union s; u: U := if odd? random(10) then ui else us; if u case Integer$'Integer' then { "Integer"; } else { "Float"; } }
Compiling FriCAS source code from file /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/2258505555743574552-25px008.as using Aldor compiler and options -O -Fasy -Fao -Flsp -lfricas -Mno-ALDOR_W_WillObsolete -DFriCAS -Y $FRICAS/algebra -I $FRICAS/algebra Use the system command )set compiler args to change these options. "/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/2258505555743574552-25px008.as",line 1: #include "axiom" ^ [L1 C1] #1 (Error) Could not open file `axiom'.
The )library system command was not called after compilation.
Untagged unions are not supported by Aldor, thus all unions must be converted to tagged unions. This means that Union(Integer, Float) needs to become something like AXIOMTypeUnion?(i:Integer, f:Float). The case statement requires the tag as its first argument, case thus you write x case i instead of x case Integer. Converting to and from tagged unions is essentially the same as with AXIOMTypeRecord? types. To create a union value from one of its branches, you wrap the value in square brackets, thus [3.3]? converts the float value ``3.3'' to a union value. Similarly, if x has type AXIOMTypeUnion?(i:Integer, f:Float), x.i converts x to an Integer value taking a runtime error if x was in the other branch of the union (for more information on unions in Aldor see part II). Partial functions in old AXIOM were often declared as returning AXIOMTypeUnion?(%, "failed"); by convention this is represented in Aldor as AXIOMTypeUnion?(value1:%, failed: failed) (recall that failed is syntactic shorthand for AXIOMTypeEnumeration?(failed)).