And what is the preferred way of type declaration?
Personally I like the second variant more, that is

f : A ->  B
f x == ...

instead of

f(x : A) : B == ...

As far as I remember, I had problems with the f(x : A) : B == ... form. But since I have no concrete example at hand, it might be my bad memory. AND I would definitely consider this as a bug if that form doesn't work!!!

Why?

Look at (the Aldor program):

---rhxBEGIN p.as
#include "axllib"
#pile
Z ==> Integer
Dom(A: Ring, B: Ring, C: Ring): with
  f: A -> B
  f: B -> B
  f: A -> C
 == add
  f(a: A): B == 0$B
  f(b: B): B == 1$B
  f(a: A): C == -1$C

main():() ==
        import from SingleInteger
        A ==> SingleIntegerMod(5)
        B ==> Z
        C ==> Ratio(Z)
        import from Dom(A, B, C), A, B, C

        fab: B := f(1$A)
        fbb: B := f(0$B)
        fac: C := f(0$A)

        print << "fab = " << fab << newline
        print << "fbb = " << fbb << newline
        print << "fac = " << fac << newline

main()
---rhxEND p.as

aldor -fx -laxllib p.as && ./p
fab = 0
fbb = 1
fac = (-1/1)

And now try to remove the type decorations in the add part of Dom. The compiler would have no clue what f belongs to what export declaration.

The following also compiles in SPAD.

---rhxBEGIN p.spad
)abbrev package DOM Dom
Z ==> Integer
Dom(A: Ring, B: Ring, C: Ring): with
  f: A -> B
  f: B -> B
  f: A -> C
 == add
  f(a: A): B == 0$B
  f(b: B): B == 1$B
  f(a: A): C == -1$C
---rhxEND p.spad

However...

(1) -> A==>PrimeField 5
                                       Type: Void
(2) -> B==>Integer
                                       Type: Void
(4) -> C==>Fraction Integer
                                       Type: Void
(5) -> Dom(A,B,C)

   (5)  Dom(PrimeField(5),Integer,Fraction(Integer))
                                       Type: Type
(6) -> )sh Dom
 Dom(A: Ring,B: Ring,C: Ring)  is a package constructor
 Abbreviation for Dom is DOM
 This constructor is exposed in this frame.
------------------------------- Operations --------------------------------
 f : A -> B                            f : B -> B
 f : A -> C

(6) -> fab: B := f(1$A)

   (6)  0
                                       Type: Integer
(7) -> fbb: B := f(0$B)

   (7)  0
                                       Type: Integer
(8) -> fac: C := f(0$A)

   (8)  0
                                       Type: Fraction(Integer)

Looks more like the current SPAD compiler is not capable of dealing with such function definitions.

Look at page 1122 of the AxiomBook (Tim's version, in the original book it's page 711):
-----
*overloading*
the use of the same name to denote distinct operations; an operation is identified by a signature identifying its name, the number and types of its arguments, and its return types. If two functions can have identical signatures, a package call must be made to distinguish the two.
-----
Well, the documentation is not really clear whether in SPAD one can define functions f(a: A):B == ... and f(a: A): C == ... in the same scope, but it should be possible.

I would interpret the above behaviour as a compiler bug.

Anyway, my preference is to exactly give the types, i.e. write in the form

  f(a: A): B == ...

because of all this overloading business.

Furthermore, how can you be sure that

  f: (A, B) -> C
  a: A
  f(a) == -1$C

should not compile? It declares some type (A, B) -> C for an f (which is never used) and then defines a (local) function f with signature f: A->C. Why should that even give a compile time error? Currently the SPAD compiler rejects that. Good (IMHO, because the return type of f(a) is not immediately visible if the function body were a bit bigger)!
But

)abbrev package DOM Dom
Z ==> Integer
Dom(A: Ring, B: Ring, C: Ring): with
  g: A -> B
 == add
  g(a: A): B == 0$B
  f: (A, B) -> C
  f(a:A):C == -1$C

compiles fine. That's also OK.

You will see that in large programs (not written by you --- try to look into src/algebra/*.pamphlet), you will sometimes have a hard time figuring out what the actual types of the function parameters are. (The type declaration just must be before you implement the function, but can be *somewhere* higher up.) I consider this search a waste of time. A human being is not a compiler.

Sure, it's easier to let the compiler figure out what the types are when you write a program, but in order to understand someone else's program you will appreciate if you see the type decorations explicitly.

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.

Reply via email to