Hi Sergei,
I can keep the part about the Axiom book relatively short. It exactly
has these deficiencies you mention. There is no clear separation of
language and library.
Although Aldor is still not free software, looking into the Aldor User
Guide (AUG), is IMHO the best source to understand the principles of
SPAD. There are a few differences, and maybe we should open up a page on
the axiom-wiki to list all of them, but in a first iteration you can
completely ignore these differences.
The AUG clearly distinguishes between language and library.
The three languages
That's somehow true.
* Aldor: (.as files) Not really relevant at the moment since it is not
free, but it can be used as a library language similar to the SPAD language.
* SPAD: (.spad files) That's the main language for writing library code.
It's only slightly differing from Aldor.
* Interpreter-Language: (.input files) That is actually not a language
of its own. It is rather the language that is used at the FriCAS prompt.
It is mainly identical with SPAD, but where the SPAD compiler is picky
about the types, the interpreter is more relaxed and tries to figure out
type information. It often guesses right what the user wanted, but it
might also fail. In other words, the interpreter tries to throw in
missing coercion function which you have to mention explicitly in a
.spad file.
I suggest to insert in many appropriate places in this books the phrases
like
"the Axiom library has the domain constructor Polynomial, which ...",
"the Axiom language has the constructs of Category, Domain,
type declaration ...".
That would certainly help and it should be done. There's simply not
enough manpower for this. In fact, the Axiom Book needs a whole rewrite.
Comparison to some Haskell features
-----------------------------------
a) Union of types is good.
b) `case x<type>' is good.
c) Using Subdomain, `pretend' looks good.
I don't like Subdomain and I thought we had removed it from FriCAS, but
I still find it in integer.spad.pamphlet. And pretend should only be
used in very special instances. It's inherently type-unsafe.
d) Rules are good,
because rule sin(2*x) == 2*sin(x)*cos(x)
cannot be written as sin(2*x) = 2*sin(x)*cos(x) in Haskell.
The Haskell programs often compute by pattern matching, but not of
the LHS part of such kind.
That's not part of the SPAD language. It looks, however that "rule" is a
construction in the interpreter language that hands its arguments over
to some library-defined functions. Am I wrong?
e) Clarity of the code.
For example, consider the lexicographic list comparison:
lexListComp :: Ord a => [a] -> [a] -> ComparisonValue
lexListComp xs ys = case (xs, ys)
of
([], [] ) -> EQ
([], _ ) -> LT
(_, [] ) -> GT
(x: xs', y: ys') -> case compare x y
of
EQ -> lexListComp xs' ys'
v -> v
(no `val', no `defun', few parentheses,
the long word `lexListComp' is not repeated).
What is the nicest code for this in Spad ?
I can only give it in Aldor. Since the Aldor library already has
something like the 3-valued comparison (in the Axiom-library, I am not
aware of such a thing, but of course it can be easily added.)
---rhxBEGIN lex.as
#include "aldor"
LexListCompare(T: TotallyOrderedType): with {
lexListComp: (List T, List T) -> MachineInteger;
} == add {
lexListComp(x: List T, y: List T): MachineInteger == {
empty? x => {if empty? y then 0 else 1}
empty? y => -1;
import from T;
v := compare(first x, first y);
v=0 => lexListComp(rest x, rest y);
v;
}
}
---rhxEND lex.as
Usually, one would even use "compare" in place of "lexListComp", but
since List(...) is already of type TotallyOrderedType, that would lead
to a conflict during compilation.
Aldor/SPAD does not have quantification over all types, so you have to
wrap everything into a package and give the respective type as a
parameter. Haskell's type class "Ord" is represented by
"TotallyOrderedType".
In fact, my code above is not 100% equivalent to the Haskell thing,
because you basically add a new function that works over all lists as
long as the argument of list provides "Ord".
The true equivalence in Aldor (which is currently not possible in SPAD,
since SPAD does not have the "extend" keyword) would be:
#include "aldor"
extend List(T: TotallyOrderedType): with {
compare: (List T, List T) -> MachineInteger;
} == add {
compare(x: List T, y: List T): MachineInteger == {
empty? x => {if empty? y then 0 else 1}
empty? y => -1;
import from T;
v := compare(first x, first y);
v=0 => compare(rest x, rest y);
v;
}
}
This even compiles fine with the current Aldor compiler.
Another question is about nested local values introduced by let-in and
"where". For example,
f x = let (p: (y, z): _) = g x x
h ys = let h' = (\ x -> [x]) in ...
in
h [p, y, z]
Oh, you assign by pattern matching. That doesn't work in Aldor/SPAD.
Otherwise, a function body opens up new scope. To get a similar pattern
to your code let's assume that
g: (T, T) -> (A, B, C)
is the type for g where T,A,B,C,Z are known from the surrounding code.
f(x: T): Z == {
(p, y, z) := g(x, x);
h(ys: List A): Z == {hh(x: A): List A == ...; ...}
h [p, y, z]
That should roughly work.
Dependent types
---------------
Also there exists a particular question of dependent types and
dependent instances (domains). In Haskell they are not possible.
In Aldor it's possible. SPAD might have some problems.
Maybe other people come up with more insight.
Ralf
--
You received this message because you are subscribed to the Google Groups "FriCAS -
computer algebra system" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/fricas-devel?hl=en.