axiom-developer
[Top][All Lists]

## RE: [Axiom-developer] RE: Cast = pretend in Spad/Aldor?

 From: Bill Page Subject: RE: [Axiom-developer] RE: Cast = pretend in Spad/Aldor? Date: Tue, 22 Nov 2005 13:35:18 -0500

```Tim,

When I read through your email I have to admit that I felt a
little depressed. I hope I don't sound too "condescending" by
saying this, but I felt like your email moves the discussion
of types in Axiom backwards to nearly "high school programming"
levels, not even computer science 101... :(

In fact I do feel peculiar about taking this role (again). Although
I have been working with computer algebra systems of a long time
(mostly Maple) and programming for much longer, I was never part
of the original group of Axiom developers and I know that you were,
yet lately I always seem to be presumptuously defending positions
that I imagine some of the other members of that team might have
held.

But we do have to start some where I guess. I will try to explain
below what I mean and see where we can go from here.

On November 22, 2005 4:00 AM Tim Daly (root) wrote:

>
> The example
>
> > (1) -> I:Integer
> >                                                 Type: Void
> > (2) -> F:Float:=1.0
> >
> >    (2)  1.0
> >                                                 Type: Float
> > (3) -> I := F pretend Integer
> >
> >    (3)  1()
>
> 'pretend' is only for system-internal use.  it basically says:
> i KNOW the exact internal representation of this thing so trust
> me.

No that is not true. 'pretend' (at least as embedded in the rep
and per macros) is essential for programming domains in the Axiom
library. This is the kind of programming that we would expected
an experienced mathematician to do - not a system-internals
programmer.

Axiom is supposed to support strong static typing. This would not
be true of it where necessary to know exact internal representations
in order to use fundamental simple constructs in the language.

When I write 'F pretend Integer' it should mean something that
can be expressed in the Axiom programming language without
reference to the internal representation.

> But here is the exact internal rep of 1.0 (at some level)
>
> (1) -> )lisp trace |pf2Sex|
> (2) -> 1.0
>    1
> (|pf2Sex| ((|float| (|posn| (0 "1.0" 1 1 "strings") .
> 0)) . "1.0e0"))
>   <1 (|pf2Sex| ((|\$elt| (|Float|) |float|) 1 0 10))
>
>    (2)  1.0
>
>                                Type: Float
> (3) -> 1
>    1
>   1> (|pf2Sex| ((|integer| (|posn| (0 "1" 1 1 "strings") . 0)) . "1"))
>   <1 (|pf2Sex| 1)
>
>    (3)  1
>                                  Type: PositiveInteger
>
> so you're lying to Axiom and it shows.

I don't know what you mean by "lying to Axiom". Programming is
not a dialogue where one party can lie to another. In the example
above I gave the Axiom interpreter a simple command which is
clearly allowed in the language. In fact, we should easily be
able to agree that this kind of command, although not this
specific example, is essential to the way we use Axiom.

>
> pretend is used in algebra code when you've created a primitive
> domain representation that has an exact representation of
> another domain as a lisp object.

No where have I ever read anything in reference to 'pretend'
about representations as lisp objects or even that the algebra
code must always have a representation as a lisp object. I think
defining the semantics of a high level language in terms of it's
specific implementation is wrong, at least in those cases where
it is avoidable. It is like saying in order to program in C I have
to know the specific machine architecture on which I am going to
compile my program.

In a related thread with Gaby on this list we have been discussing
the (cast) operator in the C programming language. Gaby has
pointed out (my paraphrase) that use of this construct has been
standardized in such a way as to remove (where possible) any need
to rely on knowledge of the internal representation.

Certainly in other high level languages related to Spad such as
Haskell and ML, there is seldom if any need to know the details
of internal representations.

But still in the algebra code, 'pretend' is necessary for the
implementation of the representation of objects in a domain. This
representation is "internal to the object" but it is not (or at
least should not require knowledge of) the internal representation
of Spad itself. The internal representation of the object should
be presented in terms of Spad data structures. The use of
'pretend' in this case allows a mapping from internal Spad data
structures to a new external object in the domain being defined.
All of this should be done *within* the Spad language itself.

> So you can do things like (from outform.spad)
>
>           sex :=
> interpret(packageTran(ncParseFromString(s)\$Lisp)\$Lisp)\$Lisp
>           sCheck := car(car(sex))
>           if (sCheck=sexfloat) = true then
>              f := (cdr cdr sex) pretend Float
>           else
>              if integer?(cdr sex) = true then
>                 f := (cdr sex) pretend Integer
>                 f::F
>              else
>                 error "Non-numeric value"
>
> notice that you've actually grabbed the output of a lisp function
> (thus the calls to \$Lisp) and are manipulating it to find the
> exact representation of the algebra object. if you use pretend
> you MUST understand the underlying lisp representations.
>

I do not agree. This is the Spad programming language. It is not
Lisp. When I make a package call to a function in \$Lisp I expect
the result to be something well defined at the Spad level. It is
the responsibility of these functions to prepare their output in
a manner that is compatible with Spad. And in the example that you
give above, this is that case. The type of the variable 'sex' is a
domain in Spad called SExpression. The things you can do with
SExpression are defined by that domain in Spad.

The constructions '(cdr cdr sex) pretend Float' and
'(cdr sex) pretend Integer' seem to me to be poorly chosen
in this usage since as you say, the correct interpretation
depends on a detailed knowledge of the implementation of
Float and Integer. These values should be defined instead
in terms of operations available within the Float, Integer
and SExpression domains themselves. In fact there is an
operation 'integer' with SExpression so we can write

f := integer(cdr sex)

and there is no need to know the implementation details.
Similarly there is an operation 'float' which might be used
to produce the desired here although it's output is of type
'DoubleFloat' not Float.

> you'll also note that this makes it hard to move the axiom
> algebra off of lisp and onto aldor. aldor needs to have the
> exact representation that axiom uses which implies that aldor
> would have to have a lisp-like internal data representation.
> so first you have to create a common lisp in aldor then ....
>

No! That is completely incorrect. In discussions with Peter
Broadbery it is clear that Aldor uses a different internal
representation that Spad for most (all?) Axiom data structures
but that does not prevent us from writing Axiom library code
using both Spad and Aldor. It does mean however that hidden
internally there must be some conversion between representations.
That is done by the Aldor interface that Peter has provided.
When this is working properly it should never be necessary for
an Axiom library programmer to know anything about these
different representations.

> this was the design issue with an aldor C implementation that
> i most strongly disagreed with. as long as you don't try to
> cross the aldor-axiom internal representations nothing will
> break. an aldor rewrite of the spad compiler in common lisp
> would not have this issue.

I think perhaps that you do not understand clearly what is
involved in the abstraction of types in high level languages
so your argument with the use of C to implement Aldor is quite
misplaced.

>
> in theory you COULD rewrite this into aldor if you moved the
> whole system but you'd have to have primitives like CAR which
> understood and could manipulate the underlying code for the
> domain as data.

Having operations like CAR is natural if you have a domain
which implements lisp-like list structures - as Axiom does.

>
> this is why lisp wins as an implementation language because
> the program==data duality allows this. i don't know how to
> rip and tear a C program as data. how do you get the "first
> statement" out of a C function, replace it with a different
> statement and then execute it? the parenthesis syntax matters.
>

Functions are not first order objects in C but they are in
other languages. If there was a good reason to implement an
operation like "get the first statement" from a function then
this could be done in many other languages besides lisp. But
usually there are much better and more rigorous ways to
manipulate functions as data without resorting to a procedural
statement but statement representation. The ability to do
that naturally is relatively unique to lisp but it does not
give lisp any particular advantage of languages like Haskell.

... and here we are back at the language war-ing again ...

<sigh>

Regards,
Bill Page.

```

reply via email to