On 07/29/2006 08:21 AM, Bill Page wrote:
Hmmm... I see. A constant that is not constant... Generators are
"mutable"? That seems like a very peculiar and questionable semantics
to me!
Hmm, I don't know what to say here about that semantics. Now if you
mention it, I don't even know if this is explained in the AUG.
But yes, Generators are mutable.
I remember that I have once seen a library implementation of "Generator"
where there appeared a "step!" function (this one is still in axllib).
Already from the name you would believe that there is some destructive
operation going on internally. For libaldor the function is called "next!".
But think about this.
gen: Generator Integer == generate {yield 0; yield 1}
for i in 1..1 for g in gen repeat stdout << g << newline;
for i in 1..1 for g in gen repeat stdout << g << newline;
You would probaly want to see two 0s as output. Right?
But you could also say (gen defined as above and then)
stdout << (next! gen) << newline;
stdout << (next! gen) << newline;
Of course, you see 0 and 1 as output and you might have expected it
since you used a BANG function (next!).
But maybe you are right, constants should remain constants even in the
case of Generators. That is actually a good question about the semantics
of "Generator" and it should be made clear.
Look at the end of Section "5.14 Loops". There you'll find the "step!"
function mentioned explicitly. But that still doesn't mean that
gen: Generator Integer == ...
should be mutable. If it were ":=" above, OK, but it's "==".
So if I write:
for x in const repeat
...
for x in const repeat
...
The 2nd loop is guarranteed never to execute?!
Currently that is the case. And believe me, that strange behaviour has
already caused me some trouble.
But if I have some other constant constant like a list
const2: List Integer == [1,2,3]
for x in const2 repeat
...
for x in const2 repeat
...
or even
for x in 1..10 repeat
...
for x in 1..10 repeat
...
this works as expected even though in Aldor iteration over a list
is implemented as a generator.
Oh, that is easy to explain. Remember, we are not in Axiom. The only
thing that can appear after "in" in Aldor is a generator. But const2 or
1..10 isn't such a thing. So Aldor adds syntactic sugar, namely it puts
a function application "generator" just at the right place. So in fact
your code then reads like
for x in generator const2 repeat ...
for x in generator 1..10 repeat ...
So each time that "for x in const2 repeat" appears in your code, a *new*
thing of type "Generator Integer" is constructed from the list const2
or from the IntegerSegment(Integer) given by 1..10.
Further what does this have to do with the type of the constant,
i.e. whether it is
const: Generator Integer
or
const: () -> Generator Integer
Do you know of any other language where Generators have the
same semantics as in Aldor?
I agree. Constants should remain constant unless you do explicit
destructive things with them. For the constant gen from above I don't
consider
for i in gen repeat ...
to be a destructive operation on "gen", since it is totally invisible
that there is a BANG function anywhere.
Even if the at runtime the state of the generator must be change, I
think the compiler should produce code so that the two for loops produce
exactly the same output.
for i in 1..1 for g in gen repeat stdout << g << newline;
for i in 1..1 for g in gen repeat stdout << g << newline;
So in fact, the compiler could make a copy of the *constant* gen before
it is given to the "for" loop. (Unfortunately there is no "copy"
functions for "Generator"s yet, and I even believe that such a function
is (nearly) impossible to write efficiently, because you might have
Generators that depend on Generators.
However, I believe it is OK, if "next! gen" modifies the constant. It is
in the responsibility of the programmer not the do anything harmful if
s/he uses BANG functions.
Ralf
_______________________________________________
Axiom-developer mailing list
Axiom-developer@nongnu.org
http://lists.nongnu.org/mailman/listinfo/axiom-developer