[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Axiom-developer] CAS for the masses

From: Ralf Hemmecke
Subject: Re: [Axiom-developer] CAS for the masses
Date: Fri, 30 Mar 2007 13:41:42 +0200
User-agent: Thunderbird 2.0b2 (X11/20070116)

On 03/30/2007 11:00 AM, Bill Page wrote:
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 ...]
  == add
    [... left out some code ...]
    B : Record(Bn:I, Bm:I, Bv:I) := [0,0,0]
    [... left out some code ...]
    binomial(n, m) ==
       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.

You certainly know that a package is nothing else than a domain that does not use %.

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.

So, it's a local variable for the

  add { ... }

one cannot see it outside unless you export it.

In fact, if you don't say

  local B: ...

then the anonymous add {...} domain exports B, but usually we restrict that through some category by naming the domain.

> 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.

Yep, in OO-term it's probably better called a state.

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.

Right. But == does not forbid that you do nasty things with the lhs. And using a destructive operation like set! is "nasty" and thus can modify constants. Well in Aldor identifiers that are defined by via == are thus not really constants.

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
of the domain B, and immediately (at instantiation time of B) fills it
with appropriate data. So the code inside the + and * constructor looks

generatingSeries: ExponentialGeneratingSeries == new();
      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?

But see, generatingSeries is like the B that is used in binomial. It is nothing like an exported constand that has a Record structure underneath. I just modify something inside the Record. Of course the place of the record itself cannot be changed. generatingSeries is just a pointer to that record. I cannot change that pointer, but I can change the data that it points to.

Who would forbid me to use set! on generatingSeries again after the domain B (now from B == X + B*B) was instantiated. set! is destructive so the programmer should know what s/he is doing. It is dangerous in general, but used wisely, it sometimes helps, like in this series case.

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.

I already agreed on that one.

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.
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.

No, but is that possible in Python?

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.

Right, modifying a domain by adding or removing functions from it is not possible in Aldor. Is this good or bad or just different?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]