Hello,
On Fri, 21 Jul 2006 10:37:30 +0200, Ralf Hemmecke <[EMAIL PROTECTED]> wrote:
Hello Christian,
On 07/21/2006 09:47 AM, Christian Aistleitner wrote:
[...]
#include "aldor"
import from String, TextWriter, Character;
define CatA: Category == with { }
define CatB: Category == with { }
define SomeCat: Category == with { CatA; CatB; }
Dom: SomeCat == Integer add;
B: CatA == Dom;
stdout << "B has CatA: " << ( B has CatA ) << newline;
stdout << "B has CatB: " << ( B has CatB ) << newline;
func( DomParam: CatB ):() == { stdout << "called func" << newline; }
C_ALL=C /opt/aldor/bin/aldor -M no-abbrev -C args=-Wopts=-m32 -Fx
-lalgebra -laldor -D IFCLAUSE test2.as && ./test2
cc1: note: -fwritable-strings is deprecated; see documentation for
details
cc1: note: -fwritable-strings is deprecated; see documentation for
details
B has CatA: T
B has CatB: T
We see B's dynamic type has bath CatA and CatB.
However,
func( B )
complains about B being only CatA and not also CatB.
func( Dom )
works.
I don't see what you mean.
I wanted to elaborate on the possible uses for ": SomeType" in statements
like "SomeIdent: SomeType == SomeThing". Indeed I explained that in the
part you chopped off when quoting:
If Ident *is* Dom then what do you think the ": SomeType" is for?
May it's syntactic sugar (maybe I should drop the "syntactic").
You can use it to restrict the static type.
The above code shows, how to get an equivalent ( B ) for a domain ( Dom )
having a different static type ( SomeCat opposed to CatA ).
Dom has static type SomeCat and dynomic type SomeCat.
B has static type CatA and dynamic type SomeCat.
What about the following:
Universe of the compiler before B: CatA == DOM:
Dom ( StaticType: SomeCat; Implementation at memory location 123456 )
After the B: CatA == Dom:
Dom ( StaticType: SomeCat; Implementation at memory location 123456 )
B ( StaticType: CatA; Implementation at memory location 123456 )
That would be OK for me, but currently the last line probably reads
B ( StaticType: SomeCat; Implementation at memory location 123456 )
since the ": CatA" has no influence on the type of B. (That's what the
compiler says. I am not sure what the language defines in that case.)
Could you underpin that with code? Because from my point of view, B does
not have static type SomeCat. B has static type CatA and dynamic type
SomeCat. I wanted to indicate this dynamic type by "implementation at
memory location 123456). In the above piece of code, you cannot use B
where CatB is expected (func( B )). Hence, B cannot have SomeCat.
---BEGIN aaa5.as
#include "aldor"
define CatA: Category == with;
define CatB: Category == with;
define CatX: Category == with;
A: Join(CatX, CatA) == add;
B: Join(CatX, CatB) == add;
#if ADD
import from MachineInteger;
X: CatX == if odd? random(10) then (A add) else (B add);
#else
X: CatX == if true then A else B;
#endif
---END aaa5.as
>aldor -fx -laldor -DADD aaa5.as
compiles without any complaints. Now try without the ADD assertion.
>aldor -fx -laldor aaa5.as
"aaa5.as", line 14: X: CatX == if true then A else B;
...........^
[L14 C12] #1 (Error) Have determined 0 possible types for the
expression.
Subexpression `A':
Meaning 1:
Join(CatX, CatA) with
==...
Subexpression `B':
Meaning 1:
Join(CatX, CatB) with
==...
The context requires an expression of type CatX.
Are you now a bit more puzzled?
Random things are not the problem. Obviously "A" and "A add" are not
(treated) identical by the compiler.
It's getting tricky to put my thoughts into correct words, but I guess:
Once the value of "A" and "A add" are established, they are treated
equally. But these expressions give different values. "A add" gives an
expression of type CatX. "A" gives an expression of type Join( CatX,
CatA ). And the compiler cannot infer properly, that Join( CatX, CatA )
provides CatX.
I think I should try a little piece of code here to claim that "A add"
cannot just give something of type CatX. We all know that it is a
perfect value in Aldor and thus must have a type of its own. The only
type I can think of for "A add" is that of "A" so it would be
Join(CatX,CatA). But then some miracles happen if you say
X: CatX == A add;
That simply forgets the CatA exports.
That's no miracle to me. Consider the statement
A: B == C add D
The "add" cuts off (mostly) all things of C such that the type of the cut
C and D meet B.
So in your example the "add" may cut off all fields of A that are not
needed by CatX.
Now let's make things a bit more complicated. Would you be able to guess
the output of the following program?
---BEGIN aaa7.as
#include "aldor"
#include "aldorio"
define CatA: Category == with;
define CatX: Category == with;
A: Join(CatX, CatA) == add;
X: CatX == A add; stdout << (X has CatA) << newline;
Y: CatX == A; stdout << (Y has CatA) << newline;
#if WITHZ
Z: CatA == Y; stdout << (Z has CatA) << newline;
#endif
---END aaa7.as
Right.
>aldor -grun -laldor aaa7.as
F
T
>aldor -DWITHZ -grun -laldor aaa7.as
"aaa7.as", line 11: Z: CatA == Y; stdout << (Z has CatA) << newline;
...........^
[L11 C12] #1 (Error) There are 0 meanings for `Y' in this context.
The possible types were:
Y: CatX, a local
The context requires an expression of type CatA.
So the compiler now thinks that the type of Y is just CatX. OK, but then
why can the program print "T" in the previous compilation?
Because Y has static type CatX and dynamic type with{ CatA; CatX; }.
The compiler uses the static type to check if Y can be used in "Z: CatA ==
Y".
The "has" checks the dynamic type.
If that is not to be considered a bug then I don't know what to say.
No bug for me ;)
Now if we assume that
X: CatX == if true then A else B;
yield an X of the type of the domain on the right hand side then the
compiler has to match the types of A and B (they have to be equal).
No. Their least common type has to be at least CatX. But we saw that Aldor
is not too good when working out types across conditional statements ;(
Try to replace B by A in the code above and the compiler will not
complain anymore.
Not true for me--I still get the corresponding errors:
Sorry, I meant
X: CatX == if true then A else A;
(no B anymore).
Then it's obvious. The compiler can infer the proper types. In both
branches, the type is TypeOfA (whatever this value was). Then inference
is easier, as the least common type is again TypeOfA.
---BEGIN aaa6.as
#include "aldor"
#include "aldorio"
macro I == MachineInteger;
define CatX: Category == with {foo: () -> I}
A: CatX == add {foo(): I == 0;}
B: CatX == add {foo(): I == 1;}
import from MachineInteger;
X: CatX == if odd? random(10) then A else B;
main(): () == {
import from X;
stdout << foo() << newline;
}
main();
---END aaa6.as
[ ... ]
The interesting part of aaa6.as is that now if one writes
X: CatX == if odd? random(10) then (A add) else (B add);
(with the "add"), the program does not compile anymore in contrast to
aaa5.as above.
>aldor -fx -laldor aaa6.as
"aaa6.as", line 13: stdout << foo() << newline;
..................^
[L13 C19] #1 (Error) There are no suitable meanings for the operator
`foo'.
But I guess, that's a different issue, as X has the foo function and
allows to call it, as demonstrated by
#include "aldor"
#include "aldorio"
macro I == MachineInteger;
define CatX: Category == with {foo: () -> I}
A: CatX == add {foo(): I == 0;}
B: CatX == add {foo(): I == 1;}
import from MachineInteger;
X: CatX == if odd? random(10) then (A add) else (B add);
main(): () == {
import from X;
stdout << (X has with{ foo:() -> I }) << newline;
stdout << ((foo$X)()) << newline;
}
main();
LC_ALL=C /opt/aldor/bin/aldor -M no-abbrev -C args=-Wopts=-m32 -Fx
-lalgebra -laldor test2.as && ./test2 && sleep 1 && ./test2
cc1: note: -fwritable-strings is deprecated; see documentation for
details
cc1: note: -fwritable-strings is deprecated; see documentation for
details
T
1
T
0
I am amazed. I had also tried foo()$X but the compiler still complained.
So the code I gave does not compile at your place?
--
Kind regards,
Christian
_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer