|
|
last edited 16 years ago by gdr |
1 2 3 | ||
Editor: gdr
Time: 2008/02/22 10:13:17 GMT-8 |
||
Note: (a,b):Integer is incorrect syntax |
added:
From gdr Fri Feb 22 10:13:17 -0800 2008
From: gdr
Date: Fri, 22 Feb 2008 10:13:17 -0800
Subject: (a,b):Integer is incorrect syntax
Message-ID: <20080222101317-0800@axiom-wiki.newsynthesis.org>
In-Reply-To: <20070908143753-0500@wiki.axiom-developer.org>
I agree with William that the syntax (a,b): Integer is inappropriate.
We should strive for a regular syntax -- otherwise things get confused
including the tools and humans. Syntactically, a comma constructs a tuple
objects, so `a,b' is a tuple of two things. If we want to type it, then
the type should be a tuple so that `(a,b): Tuple Integer' is a
destructural declaration of two things. But `(a,b): Integer' is bound to cause
problem because it appears as if we have a declaration with name `(a,b)'.
My preference would be that we reject the declaration `(a,b): Integer' - which
is invalid based on the above explanation. And we also reject
`(a,b): Tuple Integer' because, if we do accept it, then we should
logically -- for consistency -- accept `(a,b): Tuple Integer := tupleExpression'.
But we have, in general, no way to know that the initializer has exactly
two components, so we have an invitation for subtle errors.
Opinions?
The syntax for declarations which have multiple variables is given on page 142 of the Axiom book. However, using this syntax inside a function results in the compiler failing.
The first time an attempt is made to compile a function which uses this syntax, no diagnostic is produced. However, the libraries needed by the function being compiled are not loaded, and the function itself is not executed (or at least it doesn't produce any output). If a second attempt is made to execute the function, a "System error" results.
The following session transcript demonstrates the problem. It attempts to execute two functions. The first of these, named "bug", demonstrates the behavior described above. The second function, named "nonbug", is identical to "bug" except that the declaration containing two variables has been replaced by two declarations each containing a single variable. Axiom handles the "nonbug" function correctly, demonstrating that the problem is triggered by a declaration containing multiple variables. The transcript follows:
$ axiom AXIOM Computer Algebra System Version: Axiom (April 2006) Timestamp: Wednesday June 21, 2006 at 03:45:56 ----------------------------------------------------------------------------- Issue )copyright to view copyright notices. Issue )summary for a summary of useful system commands. Issue )quit to leave AXIOM and return to shell. -----------------------------------------------------------------------------Re-reading compress.daase Re-reading interp.daase Re-reading operation.daase Re-reading category.daase Re-reading browse.daase (1) -> (1) -> bug(x) == (local a, b; (a, b) : Integer; 1) Type: Void (2) -> bug(1) Compiling function bug with type PositiveInteger -> PositiveInteger (2) -> bug(1)
>> System error: (|Tuple| |a| |b|) is not of type SYMBOL.
(2) -> nonbug(x) == (local c, d; c : Integer; d : Integer; 1) Type: Void (3) -> nonbug(1) Compiling function nonbug with type PositiveInteger -> PositiveInteger
Loading /home/ka/w/axiom/mnt/linux/algebra/PI.o for domain PositiveInteger Loading /home/ka/w/axiom/mnt/linux/algebra/NNI.o for domain NonNegativeInteger Loading /home/ka/w/axiom/mnt/linux/algebra/INT.o for domain Integer Loading /home/ka/w/axiom/mnt/linux/algebra/OUTFORM.o for domain OutputForm Loading /home/ka/w/axiom/mnt/linux/algebra/LIST.o for domain List (3) 1 Type: PositiveInteger (4) -> )quit
(1) -> nobug(x) == (local a,b; a, b : Integer; a:=b:=1; a+b)
nobug(1)
Compiling function nobug with type PositiveInteger -> Integer
(1) |
bug(x) == (local a,b; (a, b) : Tuple Integer; a:=b:=1; a+b)
bug(1)
Cannot convert right-hand side of assignment 1
to an object of the type Tuple(Integer) of the left-hand side.
Also, when I tried this in my Windows version, I got:
AXIOM Computer Algebra System Version of Tuesday November 30, 2004 at 21:11:14 ----------------------------------------------------------------------------- Issue )copyright to view copyright notices. Issue )summary for a summary of useful system commands. Issue )quit to leave AXIOM and return to shell. -----------------------------------------------------------------------------(1) -> bug(x) == (local a, b; (a, b) : Integer; 1) Type: Void (2) -> bug(1) Compiling function bug with type PositiveInteger -> PositiveInteger
>> System error: (|Tuple| |a| |b|) is not of type SYMBOL.
protected-symbol-warn called with (NIL)
So the older version caught the syntax error on first compile and run. Your example seems to me to be a syntax error that was not caught in the current version on first compile and run (I was not able to find the (a,b):Integer
in the Axiom book.) since (a,b)
is a tuple. Correct syntax is a, b:Integer
for multivariable declarations. Note that (a,b):Tuple Integer
is incorrect syntax also, since (a,b)
is not an indentifier.
(a,b):Type
is syntactic sugar in the interpreter and a,b:Type
does not define type of a
correctly (but b
is typed correctly; probably the reason to require parenthesis---this requires the interpreter parser to distinguish (a,b)
to the left of : from to the right of : ). So this is another inconsistency between interpreter and compiler, or this may be due to an original bug or an unknown difficulty in parsing the comma separator in the interpreter. Alternatively, if the compiler manual says (a,b):Type
should be okay, then it is a compiler bug and the workaround is to use a,b:Type
.
(a,b):POLY INT
a:= 11
(2) |
typeOf a
(3) |
b:= 12
(4) |
a+b
(5) |
c,d:POLY INT
LISP output: (() ())
c:=11
(6) |
d:=12
(7) |
c+d
(8) |
Why does c,d:POLY INT
produce a Lisp output? and of type Tuple Void
?
c,d: POLY INT
LISP output: (() ())
is a tuple, consisting of a symbol `c' and a declaration `d: POLY INT'. However, a declaration has type `Void', and since a Tuple is a homogeneous container, both component must be brought to a common type, which is `Void'. Thus we get a Tuple Void. But, a `Void' is not coercible to OutputForm?, therefore we get the LISP output. Try
2,3
(9) |
My preference would be that we reject the declaration `(a,b): Integer' - which is invalid based on the above explanation. And we also reject `(a,b): Tuple Integer' because, if we do accept it, then we should logically -- for consistency -- accept `(a,b): Tuple Integer := tupleExpression'. But we have, in general, no way to know that the initializer has exactly two components, so we have an invitation for subtle errors.
Opinions?