The following Aldor code was given as an example by Ralf Hemmecke
and added to the wiki by Martin Rubey. See the thread:
http://lists.gnu.org/archive/html/axiom-developer/2006-07/msg00046.html
\begin{axiom}
)version
\end{axiom}
\begin{aldor}
#include "axiom"
define CatA: Category == with { }
define CatB: Category == with { }
define SomeCat: Category == with { CatA; CatB; }
Dom: SomeCat == Integer add;
A == Dom;
B: CatA == Dom;
H: CatA == Dom add;
main1():List Record(expression:String,result:Boolean) == [
["A has CatA",A has CatA],
["A has CatB",A has CatB],
["A has SomeCat",A has SomeCat],
["B has CatA",B has CatA],
["B has CatB",B has CatB],
["B has SomeCat",B has SomeCat],
["H has CatA",H has CatA],
["H has CatB",H has CatB],
["H has SomeCat",H has SomeCat]];
\end{aldor}
You get...
\begin{axiom}
main1()
)clear completely
\end{axiom}
In particular, that "B has CatB" is a bit surprising, isn't it?
Bill Page replied:
I think you are dealing here with two separate but related issues:
1) *static* typing, and 2) inheritance rules. All types in Aldor
are static (or at least *nearly static*) meaning that they must be
resolved during the compilation phase.
\begin{aldor}
#include "axiom"
define CatA?: Category == with;
define CatB?: Category == with;
define CatX?: Category == with {CatA?; CatB?;}
A: Join(CatX?, CatA?) == add;
B: Join(CatX?, CatB?) == add;
import from Integer;
X: CatX? == if odd? random(10) then A else B;
\end{aldor}
Try a little harder to create dynamic types:
\begin{aldor}
#include "axiom"
import from Integer;
define CatA?: Category == with {n:Integer};
define CatB?: Category == with {n:Integer};
define CatX?: Category == with {n:Integer};
A: Join(CatX?, CatA?) == add { n:Integer==1 };
B: Join(CatX?, CatB?) == add { n:Integer==2 };
X1: CatX? == if odd? random(10) then (A add) else (B add);
X2: CatX? == if even? random(10) then (A add) else (B add);
\end{aldor}
\begin{axiom}
for i in 1..10 repeat output [n()$X1,n()$X2]?
)clear completely
\end{axiom}
Or this way:
\begin{aldor}
#include "axiom"
import from Integer;
define CatA?: Category == with {n:Integer};
define CatB?: Category == with {n:Integer};
define CatX?: Category == with {CatA?; CatB?; n:Integer};
A: Join(CatX?, CatA?) == add { n:Integer==1 };
B: Join(CatX?, CatB?) == add { n:Integer==2 };
Y1: CatX? == if odd? random(10) then A else B;
Y2: CatX? == if even? random(10) then A else B;
\end{aldor}
\begin{axiom}
for i in 1..10 repeat output [n()$Y1,n()$Y2]?
)clear completely
\end{axiom}
Or like this:
\begin{aldor}
#include "axiom"
import from Integer;
define CatX?: Category == with {foo: () -> Integer}
A: CatX? == add {foo(): Integer == 0;}
B: CatX? == add {foo(): Integer == 1;}
Z: CatX? == if odd? random(10) then A else B;
\end{aldor}
\begin{axiom}
for i in 1..10 repeat output foo()$Z
)clear completely
\end{axiom}
Ralf Hemmecke asked:
Why does the compiler reject the program without the "add"
in line (*)?
\begin{aldor}
#include "axiom"
define CatA?: Category == with;
define CatB?: Category == with;
define CatX?: Category == with;
A: CatX? with { CatA? } == add;
B: CatX? with { CatB? } == add;
X: CatX? == if true then (A add) else (B add); -- (*)
main2():List Record(expression:String,result:Boolean) == [
["X has CatA",X has CatA]?,
["X has CatB",X has CatB]?,
["X has CatX",X has CatX]]?;
\end{aldor}
\begin{axiom}
main2()
)clear completely
\end{axiom}
Christian Aistleitner provided this answer:
I'd consider that a bug in comparison of exports. Replacing your (*) line
by:
X: CatX == if true then (A@CatX) else (B@CatX);
gives a working program.
\begin{aldor}
#include "axiom"
define CatA?: Category == with;
define CatB?: Category == with;
define CatX?: Category == with;
A: CatX? with { CatA? } == add;
B: CatX? with { CatB? } == add;
X: CatX? == if true then A@CatX? else B@CatX?; -- (*)
main3():List Record(expression:String,result:Boolean) == [
["X has CatA",X has CatA]?,
["X has CatB",X has CatB]?,
["X has CatX",X has CatX]]?;
\end{aldor}
\begin{axiom}
main3()
)clear completely
\end{axiom}
So the problem (wild guess) is that the compiler Has problems with
seeing that the if statement gives CatX? in both branches of the if
statement. Mainly because the types of A and B aro not equal. However, you
can hint the compiler. My code is telling him "The if part gives CatX? and
the else part gives CatX?". Then the compiler can infer, that the whole
"if" statement gives CatX?. And it is at least the type of X (which is
CatX?). So it matches.
\begin{aldor}
#include "axiom"
import from Integer;
define CatA?: Category == with;
define CatB?: Category == with;
define CatX?: Category == with;
A: Join(CatX?, CatA?) == add;
B: Join(CatX?, CatB?) == add;
MyPkg?(X: CatX?): with {isA?: () -> Boolean} == add {
isA?(): Boolean == X has CatA?;
}
main4(n:Integer): Boolean == {
X: CatX? == if zero? n then (A@CatX?) else (B@CatX?);
isA?()$MyPkg?(X);
}
\end{aldor}
\begin{axiom}
main4(0)
main4(1)
)clear completely
\end{axiom}
In the following code we have the correspondence:
A <--> B
String <--> with
"x" <--> String
"y" <--> Integer
\begin{aldor}
#include "axiom"
define CatA?(s: String): Category == with;
A(s: String): CatA?(s) == add;
define CatB?(s: with): Category == with;
B(s: with): CatB?(s) == add;
rhxmain(): List Record(s: String, b: Boolean) == [
["A x has CatA x", (A("x") has CatA("x"))]?,
["A y has CatA x", (A("y") has CatA("x"))]?,
["B String has CatB String", (B(String) has CatB(String))]?,
["B Integer has CatB String",(B(Integer) has CatB(String))]?
];
\end{aldor}
The interesting part is that the truth value of the second and fourth list elements do not agree.
\begin{axiom}
rhxmain()
)clear completely
\end{axiom}
An example of a domain-valued variable
\begin{aldor}
#include "axiom"
#pile
main5(n:Integer):List Boolean ==
local x:IntegralDomain?
local y:Category
if n=1 then
y := Field
else
y := Ring
x := Integer
test1:Boolean := x has y
x := Fraction Integer
test2:Boolean := x has y
[test1,test2]?
\end{aldor}
\begin{axiom}
main5(1)
main5(2)
)clear completely
\end{axiom}
The compiler checks static types.
\begin{aldor}
#include "axiom"
#pile
main6():List Boolean ==
local x:IntegralDomain?
x := Integer
test1:Boolean := x has Field
x := String
test2:Boolean := x has Field
[test1,test2]?
\end{aldor}
But note that we cannot define domain-valued variables in
the Axiom interpreter.
\begin{axiom}
x:IntegralDomain?
\end{axiom}
\begin{aldor}
#include "axiom"
#pile
MyDom?: with
sigs:List Category
add2:(MyDom?,MyDom?) -> MyDom?
sub2:(MyDom?,MyDom?) -> MyDom?
neg: MyDom? -> MyDom?
== add
import from Integer
Rep == Integer
sigs:List Category ==
[with {add2:(MyDom?,MyDom?)->MyDom?},
with {sub2:(MyDom?,MyDom?)->MyDom?},
with {neg:MyDom?->MyDom?}]
add2(x:%,y:%):% == per(rep(x) + rep(y))
sub2(x:%,y:%):% == per(rep(x) - rep(y))
neg(x:%):% == per(-rep(x))
main8():List Boolean ==
import from ListFunctions2?(Category,Boolean)
map((i:Category):Boolean+->(MyDom? has i), sigs$MyDom?)
\end{aldor}
\begin{axiom}
)sh MyDom?
main8()
\end{axiom}