axiom-developer
[Top][All Lists]

## Re: [Axiom-developer] CAS for the masses

 From: Bill Page Subject: Re: [Axiom-developer] CAS for the masses Date: Fri, 30 Mar 2007 05:00:00 -0400 User-agent: Webmail 4.0

```Quoting Ralf Hemmecke <address@hidden>:

```
```...
But aldor/spad allows to modify the domain. Here some piece of code
which even uses this in the Axiom algebra library:

IntegerCombinatoricFunctions(I:IntegerNumberSystem): with
binomial: (I, I) -> I
[... left out some exports ...]
[... left out some code ...]
B : Record(Bn:I, Bm:I, Bv:I) := [0,0,0]
[... left out some code ...]
binomial(n, m) ==
s,b:I
n < 0 or m < 0 or m > n => 0
m = 0 => 1
n < 2*m => binomial(n, n-m)
(s,b) := (0,1)
if B.Bn = n then
B.Bm = m+1 =>
b := (B.Bv * (m+1)) quo (n-m)
B.Bn := n
B.Bm := m
return(B.Bv := b)
if m >= B.Bm then (s := B.Bm; b := B.Bv) else (s,b) := (0,1)
for k in convert(s+1)@Z .. convert(m)@Z repeat
b := (b*(n-k::I+1)) quo k::I
B.Bn := n
B.Bm := m
B.Bv := b

```
```
I don't understand your example. Why do you say that it "allows to
modify the domain"? As far as I can see in

IntegerCombinatoricFunctions is a package not a domain. But in
any case, all I see is that the binomial function has a side-effect of
modifying the variable B and in turn that what it actually does depends
on this stored value when it is called again.

```
```You could argue that B is a local variable.
```
```
Technically B is not a "local" variable but rather a variable of the
instance of this package. Because of these variables the instance
has a "state". Apparently it is used here to cache the return value
to make the computation more efficient.

```
```But then define it with == to be a constant and export it. Since
"B.Bn := n" is a destructive operation, one can also modify constants.

```
```
I don't understand this statement. If I write B.Bn := n, then B is not
constant. This statement can be executed anytime during the
execution of the program. If I remember correctly the semantics of
== on the other hand is that the value of the lhs is set just once at
the time the instance is created.

```
```In Aldor-Combinat I even have to use this destructiveness in order to
allow recursive definitions of combinatorial species a la

B == X + B*B

internally that first defines a (dummy) constant for the value of the
exported symbol
generatingFunction
of the domain B, and immediately (at instantiation time of B) fills it
with appropriate data. So the code inside the + and * constructor looks
like

generatingSeries: ExponentialGeneratingSeries == new();
set!(
generatingSeries \$ %,
generatingSeries \$ F(L) * generatingSeries \$ G(L)
);

where F and G are equal to B for the above equation.

Again, since this set! function is destructive, I can apply it even
later, after the creation of the domain B. In that sense I would at
least modify an attribute of the domain.

```
```
I guess I understand what this code is doing. The key is to remember
that an == statement is executed exactly once during the initialization
phase of creating an instance but in other respects it is the same as an
assignment. I think somewhere in the Aldor Users Guide it also says
that the order in which the initializations are done is not defined so you
must be very careful with initializations that can have side-effects. But
in the end, after this initialization is done, the value of B does not
change, right?

Still, the fact that an instance of a domain or package or category
can have a state does not make the code different. Of course one
might carry this to an extreme such as having a domain that
implements a Lisp interpreter and an internal state that corresponds
to some Lisp sexpression that gets interpreted when some function
is installed. But in Aldor once the domain is compiled that actual
code of the domain that implements the Lisp interpreter is fixed
even though the function could return any result what so ever based
on it's internal state.

```
```However, you are right in the sense that what I just described is not
the most common usage of a domain. And I would even argue, to
avoid that option unless you have *very* good reason to use it. (I had,
since otherwise recursion were impossible.

But anyway that brings me to yet another example.
Didn't we have a running example of Even and Odd?

This here only shows a problem.
http://wiki.axiom-developer.org/MutualRecursion
But it's rather a minor problem, I guess.
```
```
Yes, this was due to the file rename problem in an earlier version
of Axiom. All that was needed was to click the 'refresh' button.
But I don't see this as an example of a sitation which allows to
modify the domain.

```
```
>> System error:
Cannot rename the file #p"EVEN.erlib" to #p"EVEN.NRLIB".

I have also found
http://wiki.axiom-developer.org/SandBoxAldorSemantics
but maybe that is a bit too much for a contact between Aldor and Python.

```
```Once constructed their "value" is constant and can not be changed.
```
```
Are my examples convincing, that this is not true in general.

```
```
No not really. These functions are really the *same* in the sense that
they execute the same code (as you say below). But the situation is
complicated by the fact that these functions can depend on internal
state variables.

```
``` > For example we
```
```can not insert or remove anything in the list of exports or even
replace one exported function with another during the execution
of the program. This is possible in Python.
```
```
This is on the category level. And it is true.
I also agree that after a definition

foo(x: %): % == ... some code ...

in a domain and the instantiation of that domain, it is impossible to
make that function to use other code. It might depend on some internal
state, though, as binomial above, but the function foo always executes
the same "... some code ...".

```
```
Yes! That is exactly what I mean.

```
```Note: I am not talking about the post facto library extension feature
in Aldor. 'extend' is a compile-time operation.
```
```
Then certainly 'extend' is possible in Python although not at compile-time.

```
```
Yes.

```
```In Python on the other hand new classes can be created dynamically.
See for example the method '__new__'  in
```
```
With a bit of work one can also achieve arbitrarily many instances of
Complex2(Integer). I think one just has to wrap the creation by a function.

```
```
Yes, but that is not what '__new__' does. It creates whatever class you
tell it to create at run-time. During the execution of the program you can
add new properties and methods to the class.

Regards,
Bill Page.

```