Hello!numbers from 1 to 20:
I'm playing with Oberon-07 using the obnc and oberonc compilers (which are great BTW). Today I hit on a surprise: I was sure that Oberon’s FOR loop behaved like that of Pascal, Modula-2, and Ada. That is, I thought the following should print the
i := 20;
FOR j := 1 TO i DO
Out.Int(j, 0); Out.Ln;
i := i - 1;
END;
However, in Oberon-07 reports released in 2007, 2011 and 2013 the definition was taken from Oberon-2 as is (that was slightly different from the actual).
v := beg; lim := end;
WHILE v <= lim DO S; v := v + inc END
The end condition is copied to a new variable and the WHILE is tested against that variable. That means the condition after TO is not evaluated in every repetition and is considered constant.
In my opinion, this one is the correct behaviour.
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
If you read section 9.8. in the language report you will find that the
above statement sequence is equivalent to...
i := 20;
j := 1;
WHILE j <= i DO
Out.Int(j, 0);
Out.Ln;
i := i - 1;
j := j + 1
END
http://miasap.se/obnc/oberon-report.html#sec9.8
On Tuesday, May 22, 2018 at 11:59:13 PM UTC-5, August Karlstrom wrote:
If you read section 9.8. in the language report you will find that the
above statement sequence is equivalent to...
i := 20;
j := 1;
WHILE j <= i DO
Out.Int(j, 0);
Out.Ln;
i := i - 1;
j := j + 1
END
http://miasap.se/obnc/oberon-report.html#sec9.8
I see; I was looking at PiO when perhaps I should have been looking at that document, instead. Are you saying that the reason it is not a syntax error is that "Programming in Oberon" is not as official as the language report?
On 2018-05-23 06:47, Diego Sardina wrote:
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
is that it's left unspecified whether the expression `end' is evaluated
once or each time the guard is evaluated. In that case the compiler implementor can choose one of the two evaluation strategies and the the programmer should not rely on any of them.
On Wednesday, May 23, 2018 at 10:25:19 AM UTC-5, August Karlstrom wrote:
On 2018-05-23 06:47, Diego Sardina wrote:
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
is that it's left unspecified whether the expression `end' is evaluated once or each time the guard is evaluated. In that case the compiler implementor can choose one of the two evaluation strategies and the the programmer should not rely on any of them.
In 9.6, Wirth writes, "The expression evaluation and the statement execution are repeated until none of the Boolean expressions yields TRUE."
The phrase, "the expression evaluation ...[is] repeated" would suggest to me that "end" also has to be evaluated.
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
On Wednesday, May 23, 2018 at 10:25:19 AM UTC-5, August Karlstrom wrote:
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
is that it's left unspecified whether the expression `end' is evaluated
once or each time the guard is evaluated. In that case the compiler
implementor can choose one of the two evaluation strategies and the the
programmer should not rely on any of them.
In 9.6, Wirth writes, "The expression evaluation and the statement execution are repeated until none of the Boolean expressions yields TRUE."
The phrase, "the expression evaluation ...[is] repeated" would suggest to me that "end" also has to be evaluated.
"The expression" refers to the loop guard as a whole, not the limit expression.
On Wednesday, May 23, 2018 at 11:06:56 AM UTC-5, john....@usm.edu wrote:
On Wednesday, May 23, 2018 at 10:25:19 AM UTC-5, August Karlstrom wrote:
On 2018-05-23 06:47, Diego Sardina wrote:
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
Sorry, I forgot to say something: this is especially true if "end" is a procedure, rather than a variable!
On Thursday, May 24, 2018 at 1:37:29 AM UTC+9:30, john....@usm.edu wrote:
On Wednesday, May 23, 2018 at 11:06:56 AM UTC-5, john....@usm.edu wrote:
On Wednesday, May 23, 2018 at 10:25:19 AM UTC-5, August Karlstrom wrote:
On 2018-05-23 06:47, Diego Sardina wrote:
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
Sorry, I forgot to say something: this is especially true if "end" is a procedure, rather than a variable!
Incorrect. In this example "end" could not be a procedure. If it was, in Oberon-07 it would have to be written as:
WHILE v <= end() DO S; v := v + inc END
Refer to Section 10.1 Formal Parameters.
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
--
Diego Sardina
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
consider the save/restore of registers at function calls as temporary variables).--
Diego Sardina
While developing the oberonc compiler, I remember asking Prof. Wirth why his implementation of the FOR loop was re-evaluating the "end" expression at each iteration.
In his reply he mentioned that he prefers to avoid the problem of allocating a temporary variable. Indeed, if you look at his latest compiler's source code, there is no other place where a temporary variable must be reserved in the stack frame (I don't
I think this is another example of "make it as simple as possible, but not simpler", the compiler avoid extra complexity, and the end user can always introduce manually the temporary variable in his source code, making his choice explicit.
The only thing that I find less convenient is that the range of the control variable goes all the way to the "end" value included: [begin, end]
For example, I would prefer to write
FOR i := 0 TO LEN(a) DO a[i] := -1 END;
where i is in the interval [0, LEN(a)) instead of
FOR i := 0 TO LEN(a)-1 DO a[i] := -1 END;
where i is in the interval [0, LEN(a)-1].
But this is just a matter of taste.
On Thursday, May 24, 2018 at 1:37:29 AM UTC+9:30, john....@usm.edu wrote:
On Wednesday, May 23, 2018 at 11:06:56 AM UTC-5, john....@usm.edu wrote:
On Wednesday, May 23, 2018 at 10:25:19 AM UTC-5, August Karlstrom wrote: >>>> On 2018-05-23 06:47, Diego Sardina wrote:
I don't know why in the latest report Prof. Wirth changed the FOR definition. This happened during 2016, IIRC.
One way to interpret
v := beg;
WHILE v <= end DO S; v := v + inc END
Sorry, I forgot to say something: this is especially true if "end" is a procedure, rather than a variable!
Incorrect. In this example "end" could not be a procedure. If it was, in Oberon-07 it would have to be written as:
WHILE v <= end() DO S; v := v + inc END
It should be noted that Wirth initially removed FOR loops in the transition from Modula-2 to Oberon.
On Thursday, May 24, 2018 at 1:30:43 PM UTC+9:30, cfbso...@gmail.com wrote:absence from Oberon."
It should be noted that Wirth initially removed FOR loops in the transition from Modula-2 to Oberon.
The reason given at the time was:
"The elimination of the for statement constitutes a break with another long standing tradition. The baroque mechanism of Algol 60’s for statement had been trimmed significantly in Pascal (and Modula). Its marginal value in practice has led to its
From Modula to Oberon (ModToOberon2.Doc / NW 1.10.90)
"Although for statements can always be expressed by while statements, they are sometimes more convenient because they are shorter and termination is inherent.
On Thursday, May 24, 2018 at 6:57:08 AM UTC-5, john....@usm.edu wrote:
Now imagine that the end condition is not a variable n, but a procedure that returns a boolean...
*sigh* "boolean" -> "integer"
Now imagine that the end condition is not a variable n, but a procedure that returns a boolean...
Hello!
I'm playing with Oberon-07 using the obnc and oberonc compilers (which
are great BTW). Today I hit on a surprise: I was sure that Oberon’s
FOR loop behaved like that of Pascal, Modula-2, and Ada. That is, I
thought the following should print the numbers from 1 to 20:
i := 20;
FOR j := 1 TO i DO
Out.Int(j, 0); Out.Ln;
i := i - 1;
END;
This is admittedly dumb code, but never mind that. I just checked this
with freepascal, Gnu Modula-2, and gnat, and all three produce code
that prints all the numbers from 1 to 20. I guess this is because the
value of i is evaluated at the beginning of the loop, then stored for
future tests. This can be more efficient in general, especially if the
test involves a complicated function.
In C, on the other hand,it prints the numbers from 1 to 10, because C
would evaluate the value of i on each pass through the loop.
It turns out that in code produced by obnc and oberonc, the FOR loop
behaves like C, and NOT like the other Pascal-derived languages I
mentioned.
I was sure this was a bug: why would Wirth change the semantics of a
FOR loop? I went to look in “Programming in Oberon,” and the semantics are explained on p. 21:
It is recommended that the for statement be used in simple cases only;
in particular, no components of the expressions determining the range
must be affected by the repeated statements, and, above all, the
control variable itself must not be changed by the repeated statements.
The value of the control variable must be considered as undefined after
the for statement is terminated.
Again, I concede that the loop above is bad code. Still, I’m curious:
1) Is it an error, because I modify i, violating “no components of the expressions determining the range must be affected”?
2) If so, should the compiler report an error?
3) If not, should the compiler produce code similar to Pascal et al.,
or identical to C?
I realize there's a workaround. I just want to know what the language
lawyers think of it.
I spent a long time in my youth with Pascal, Modual-2, hoping from one language to the other in search of the perfect programming language.
There's no such thing.
This is why you need a meta-programming language, such as Common Lisp,
where you can shape the language to your own needs and will, right on
the spot, when you have a problem to solve that calls for it.
This is why you need a meta-programming language, such as Common Lisp,
where you can shape the language to your own needs and will, right on
the spot, when you have a problem to solve that calls for it.
On 2018-05-24 20:43, Pascal J. Bourguignon wrote:
This is why you need a meta-programming language, such as Common Lisp,
where you can shape the language to your own needs and will, right on
the spot, when you have a problem to solve that calls for it.
I guess the price you pay for that is an added effort required to
understand a program written in such an ad hoc language.
Also, if I'm not mistaken, Common Lisp is not a system programming
language. Nor is it as efficient as compiled Oberon code.
On Thursday, May 24, 2018 at 1:43:45 PM UTC-5, Pascal J. Bourguignon wrote:
I spent a long time in my youth with Pascal, Modual-2, hoping from one
language to the other in search of the perfect programming language.
There's no such thing.
No disagreement there.
This is why you need a meta-programming language, such as Common Lisp,
where you can shape the language to your own needs and will, right on
the spot, when you have a problem to solve that calls for it.
I didn't know you could do this in LISP, but I was under the
impression that you could do something like this with the most recent
Perl (not sure; may have misread something).
I immediately wondered,
doesn't that run the risk of making code harder to read, if everyone
can write his own "dialect"? Perhaps I just don't know enough about
this sort of thing.
On 2018-05-24 20:43, Pascal J. Bourguignon wrote:
This is why you need a meta-programming language, such as Common Lisp,
where you can shape the language to your own needs and will, right on
the spot, when you have a problem to solve that calls for it.
I guess the price you pay for that is an added effort required to
understand a program written in such an ad hoc language. Also, if I'm
not mistaken, Common Lisp is not a system programming language. Nor is
it as efficient as compiled Oberon code.
I think this is another example of "make it as simple as possible, but not simpler", the compiler avoid extra complexity, and the end user can always introduce manually the temporary variable in his source code, making his choice explicit.
On 2018-05-24 04:41, Luca Boasso wrote:
I think this is another example of "make it as simple as possible,
but not simpler", the compiler avoid extra complexity, and the end
user can always introduce manually the temporary variable in his
source code, making his choice explicit.
Also, the generated code can actually be more efficient, because if the
end expression is a constant or a variable in a register, no assignment
to a a temporary variable is necessary.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 374 |
Nodes: | 16 (2 / 14) |
Uptime: | 141:16:58 |
Calls: | 7,958 |
Calls today: | 3 |
Files: | 13,011 |
Messages: | 5,814,067 |