axiom-developer
[Top][All Lists]
Advanced

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

RE: [Axiom-developer] Lazy re-evaluation (was: More AxiomUI)


From: Page, Bill
Subject: RE: [Axiom-developer] Lazy re-evaluation (was: More AxiomUI)
Date: Thu, 23 Jun 2005 17:13:15 -0400

Bob,

On Thursday, June 23, 2005 2:41 PM you wrote:

>Let me understand this better.
>
> (1) -> f(n)==(free k; k:=k+1; n+k);
>                                     Type: Void
> (2) -> f(1)
>   Loading /usr/lib/axiom-20050201/algebra/UPMP.o for package 
>      UnivariatePolynomialMultiplicationPackage 
>   Compiling function f with type PositiveInteger -> Polynomial Integer
>      
>   Compiled code for f has been cleared.
>
>   (2)  k + 2
>                                     Type: Polynomial Integer
> (3) -> f(1)
>   Compiling function f with type PositiveInteger -> Polynomial Integer
>
>   (3)  k + 3
>                                     Type: Polynomial Integer
> (4) -> f(1)
>
>  (4)  k + 4
>                                     Type: Polynomial Integer
>
> First of all, why does it claim to have compiled the function
> twice?

Interesting!

I think this must occur because the global variable k initially has
no type information. As such it defaults to being of type Variable k.

Axiom told you that it compiled the function assuming that the
function would return a Polynomial. That is a pretty smart thing
for Axiom to have guessed but it could have been wrong.

> Why does it claim after line 2 that "compiled code for f has
> been cleared"?

The message "Compiled code for f has been cleared." is avoided
if you declare

  k:Polynomial Integer

before applying f for the first time. You can also declare it as

  k:Expression Integer

or any other type that permits the operation + when k is unassigned
(it might have a type but no associate value). I presume that
Axiom does this in case the result of the first application of the
function actually resulted in k being of some other type. This
actually happens in this case but the difference in type is not
significant. To see this note that when f(1) is first called k
is of still of type Variable k by default. During the execution
of f(1) k becomes of type Polynomial Integer because of the
assignment k:=k+1.

> The "free" statement declares k to be in the global namespace,
> yet when it is assigned in f(), the output does not seem to
> know that it is a global with a bound value...???

Why do you say that? When f() is first called k is of type
Variable k and it's value is just k. During the execution of
f() k becomes something of type Polynomial Integer and its
value is set of k+1 where the k in this expression refers to
the k of type Variable k. Try this:

(7) -> )clear completely
   All user variables and function definitions have been cleared.
   All )browse facility databases have been cleared.
   Internally cached functions and constructors have been cleared.
   )clear completely is finished.
(1) -> typeOf k

   (1)  Variable k
                                           Type: Domain
(2) -> f(n)==(free k; k:=k+1; n+k);
                                           Type: Void
(3) -> f(1)
   Compiling function f with type PositiveInteger -> Polynomial Integer

   Compiled code for f has been cleared.

   (3)  k + 2
                                           Type: Polynomial Integer
(4) -> k

   (4)  k + 1
                                           Type: Polynomial Integer
(5) -> subst(k,'k=1)

   (5)  2
                                           Type: Expression Integer
(6) ->

The result of line (4) is probably quite unexpected. You can see
in fact that the k in the expression that is value of k is just the
variable 'k. Axiom apparently has no trouble with such a circularity.
And why should it?

> A similar function in Mathematica:
>
>    f[n_] == Block[{}, (k:=k+1; n+k)]
>
> complains that "Recursion depth of 256 exceeded" which makes more
> sense because it is searching for a definition of k.  (actually it
> makes that complaint even if I define k first -- I think I've not
> written an equivalent example)

In Maple I would write:

> f := proc (n) global k; k := k+1; n+k end proc
> f(1)
 Error, (in f) too many levels of recursion 

So Maple and Mathematica agree about this. But if I write:

> k:=1;
> f := proc (n) global k; k := k+1; n+k end proc
> f(1)
                   3

I can try this:

> x:= 'x' + 1;
Error, recursive assignment

which fails, but it turns out though that I can write a delayed
evaluation like this

> x:=''x'+1';
> subs('x'=1,x);
                  2

This is probably also possible in Mathematica using some similar
delayed evaluation expressions.

In Axiom I can just write this

> x:= 'x + 1

   (12)  x + 1
                        Type: Polynomial Integer
> subst(x,'x=1)

   (13)  2
                        Type: Expression Integer

No problem. 

> And the moral of the story is that side-effects suck.  Lisp
> and the lambda calculus have the right idea... ;)

I think that Axiom seems mostly to inherit this right idea.


Regards,
Bill Page.




reply via email to

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