lboasso / oberonc

An Oberon-07 compiler for the JVM
MIT License
146 stars 17 forks source link

Inconsistent Behaviour of For Loop #33

Closed geekstakulus closed 8 months ago

geekstakulus commented 8 months ago

Introduction

In Oberon-07 and its predecessors, the for loop is designed to iterate a fixed number of times. As such, the control variable within the loop should remain constant, and the expression following the "TO" keyword should also be fixed.

Current Behavior

Currently, the Oberonc compiler flags modifications to the control variable within the loop body as errors. However, it doesn't enforce the immutability of the expression following the "TO" keyword. Consider the following two code snippets:

MODULE ForLoop1;
    IMPORT Out;
    VAR
        n : INTEGER;
BEGIN
    FOR n := 1 TO 5 DO
        DEC(n);
        Out.String("i = ");
        Out.Int(n, 0);
        Out.Ln
    END
END ForLoop1.

This code fails to compile due to the attempt to decrement n, which triggers an error. This behavior is expected and thus considered correct.

However, consider the next code snippet:

MODULE ForLimit;
 IMPORT Out;
 VAR
   i, limit : INTEGER;
BEGIN
 limit := 4;

 FOR i := 1 TO limit + 1 DO
   DEC(limit);
   Out.Int(limit, 0);
   Out.String(", ");
   Out.Int(i, 0);
   Out.Ln
 END;
 Out.String(":");
 Out.Int(limit, 0);
 Out.Ln
END ForLimit.

This code compiles successfully, but produces unexpected output. The expression limit + 1 should only be evaluated once, but in this case, it appears to be reevaluated with each iteration of the loop, resulting in the following incorrect output:

3, 1
2, 2
1, 3
:1

Expected Behavior

The expected behavior would be for the expression limit + 1 to be evaluated only once, producing the following output:

3, 1
2, 2
1, 3
0, 4
-1, 5
:-1

Reproduction Steps

To reproduce this behavior:

  1. Compile the code using the Oberonc compiler.
  2. Observe that the compiler throws an error on the first example.
  3. Observe that the compiler compiles the code without error on the second example, but produces incorrect output.

Additional Information

Interestingly, compiling the same code with obc yields the correct output for the second example. However, it allows the modification of the control variable within the body of the for loop, which is contrary to the expected behavior. oberonc behaves similarly to Java and C.

KevinRH commented 8 months ago

Hi,

To check the given FOR loops for correct behaviour, all you have to do is translate them into the equivalent forms described in the Oberon-04 Report (3.5.2016).

Regards, K


From: Geekstakulus @.> Sent: Sunday 31 December 2023 10:20 To: lboasso/oberonc @.> Cc: Subscribed @.***> Subject: [lboasso/oberonc] Inconsistent Behaviour of For Loop (Issue #33)

Introduction

In Oberon-07 and its predecessors, the for loop is designed to iterate a fixed number of times. As such, the control variable within the loop should remain constant, and the expression following the "TO" keyword should also be fixed.

Current Behavior

Currently, the Oberonc compiler flags modifications to the control variable within the loop body as errors. However, it doesn't enforce the immutability of the expression following the "TO" keyword. Consider the following two code snippets:

MODULE ForLoop1; IMPORT Out; VAR n : INTEGER; BEGIN FOR n := 1 TO 5 DO DEC(n); Out.String("i = "); Out.Int(n, 0); Out.Ln END END ForLoop1.

This code fails to compile due to the attempt to decrement n, which triggers an error. This behavior is expected and thus considered correct.

However, consider the next code snippet:

MODULE ForLimit; IMPORT Out; VAR i, limit : INTEGER; BEGIN limit := 4;

FOR i := 1 TO limit + 1 DO DEC(limit); Out.Int(limit, 0); Out.String(", "); Out.Int(i, 0); Out.Ln END; Out.String(":"); Out.Int(limit, 0); Out.Ln END ForLimit.

This code compiles successfully, but produces unexpected output. The expression limit + 1 should only be evaluated once, but in this case, it appears to be reevaluated with each iteration of the loop, resulting in the following incorrect output:

3, 1 2, 2 1, 3 :1

Expected Behavior

The expected behavior would be for the expression limit + 1 to be evaluated only once, producing the following output:

3, 1 2, 2 1, 3 0, 4 -1, 5 :-1

Reproduction Steps

To reproduce this behavior:

  1. Compile the code using the Oberonc compiler.
  2. Observe that the compiler throws an error on the first example.
  3. Observe that the compiler compiles the code without error on the second example, but produces incorrect output.

Additional Information

Interestingly, compiling the same code with obc yields the correct output for the second example. However, it allows the modification of the control variable within the body of the for loop, which is contrary to the expected behavior. oberonc behaves similarly to Java and C.

β€” Reply to this email directly, view it on GitHubhttps://github.com/lboasso/oberonc/issues/33, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AH3LGZPEAPDUTBNE3QBEDS3YME37DAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43ASLTON2WKOZSGA3DCMBRGI2DGNA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

lboasso commented 8 months ago

Hello,

At the time I was dealing with the code generation of the FOR loop I noticed that Wirth decided not to use a temporary variable to hold the loop upper bound in his RISC compiler, so I implemented it in oberonc in the same way. Indeed the latest language report mandates the repeated evaluation of the "end" variable. In retrospect I agree it would be better to handle it as defined in the Oberon-2 report: (https://ssw.jku.at/Research/Papers/Oberon2.pdf), but I prefer to adhere to the Oberon-07 language report and avoid creating a dialect.

I can share a patch with the necessary changes to the code to make it work as in Oberon-2, if you are interested. Years ago I experimented with it just for fun.

Cheers and happy new year, Luca

On Sun, Dec 31, 2023, 16:21 KevinRH @.***> wrote:

Hi,

To check the given FOR loops for correct behaviour, all you have to do is translate them into the equivalent forms described in the Oberon-04 Report (3.5.2016).

Regards, K


From: Geekstakulus @.> Sent: Sunday 31 December 2023 10:20 To: lboasso/oberonc @.> Cc: Subscribed @.***> Subject: [lboasso/oberonc] Inconsistent Behaviour of For Loop (Issue #33)

Introduction

In Oberon-07 and its predecessors, the for loop is designed to iterate a fixed number of times. As such, the control variable within the loop should remain constant, and the expression following the "TO" keyword should also be fixed.

Current Behavior

Currently, the Oberonc compiler flags modifications to the control variable within the loop body as errors. However, it doesn't enforce the immutability of the expression following the "TO" keyword. Consider the following two code snippets:

MODULE ForLoop1; IMPORT Out; VAR n : INTEGER; BEGIN FOR n := 1 TO 5 DO DEC(n); Out.String("i = "); Out.Int(n, 0); Out.Ln END END ForLoop1.

This code fails to compile due to the attempt to decrement n, which triggers an error. This behavior is expected and thus considered correct.

However, consider the next code snippet:

MODULE ForLimit; IMPORT Out; VAR i, limit : INTEGER; BEGIN limit := 4;

FOR i := 1 TO limit + 1 DO DEC(limit); Out.Int(limit, 0); Out.String(", "); Out.Int(i, 0); Out.Ln END; Out.String(":"); Out.Int(limit, 0); Out.Ln END ForLimit.

This code compiles successfully, but produces unexpected output. The expression limit + 1 should only be evaluated once, but in this case, it appears to be reevaluated with each iteration of the loop, resulting in the following incorrect output:

3, 1 2, 2 1, 3 :1

Expected Behavior

The expected behavior would be for the expression limit + 1 to be evaluated only once, producing the following output:

3, 1 2, 2 1, 3 0, 4 -1, 5 :-1

Reproduction Steps

To reproduce this behavior:

  1. Compile the code using the Oberonc compiler.
  2. Observe that the compiler throws an error on the first example.
  3. Observe that the compiler compiles the code without error on the second example, but produces incorrect output.

Additional Information

Interestingly, compiling the same code with obc yields the correct output for the second example. However, it allows the modification of the control variable within the body of the for loop, which is contrary to the expected behavior. oberonc behaves similarly to Java and C.

β€” Reply to this email directly, view it on GitHub< https://github.com/lboasso/oberonc/issues/33>, or unsubscribe< https://github.com/notifications/unsubscribe-auth/AH3LGZPEAPDUTBNE3QBEDS3YME37DAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43ASLTON2WKOZSGA3DCMBRGI2DGNA>.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

β€” Reply to this email directly, view it on GitHub https://github.com/lboasso/oberonc/issues/33#issuecomment-1872960637, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVJAW2LTUCSHI3QMCURU6LYMFYG5AVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZSHE3DANRTG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

KevinRH commented 8 months ago

Hi,

Sorry, I meant "Oberon-07" report (not "Oberon-04").

Oberon-2 is a different language. For me, the language definition document is "gospel" πŸ™‚ (even if it sometimes doesn't seem "right")!

Thanks, and have a great 2024!

Kevin


From: Luca Boasso @.> Sent: Sunday 31 December 2023 15:15 To: lboasso/oberonc @.> Cc: KevinRH @.>; Comment @.> Subject: Re: [lboasso/oberonc] Inconsistent Behaviour of For Loop (Issue #33)

Hello,

At the time I was dealing with the code generation of the FOR loop I noticed that Wirth decided not to use a temporary variable to hold the loop upper bound in his RISC compiler, so I implemented it in oberonc in the same way. Indeed the latest language report mandates the repeated evaluation of the "end" variable. In retrospect I agree it would be better to handle it as defined in the Oberon-2 report: (https://ssw.jku.at/Research/Papers/Oberon2.pdf), but I prefer to adhere to the Oberon-07 language report and avoid creating a dialect.

I can share a patch with the necessary changes to the code to make it work as in Oberon-2, if you are interested. Years ago I experimented with it just for fun.

Cheers and happy new year, Luca

On Sun, Dec 31, 2023, 16:21 KevinRH @.***> wrote:

Hi,

To check the given FOR loops for correct behaviour, all you have to do is translate them into the equivalent forms described in the Oberon-04 Report (3.5.2016).

Regards, K


From: Geekstakulus @.> Sent: Sunday 31 December 2023 10:20 To: lboasso/oberonc @.> Cc: Subscribed @.***> Subject: [lboasso/oberonc] Inconsistent Behaviour of For Loop (Issue #33)

Introduction

In Oberon-07 and its predecessors, the for loop is designed to iterate a fixed number of times. As such, the control variable within the loop should remain constant, and the expression following the "TO" keyword should also be fixed.

Current Behavior

Currently, the Oberonc compiler flags modifications to the control variable within the loop body as errors. However, it doesn't enforce the immutability of the expression following the "TO" keyword. Consider the following two code snippets:

MODULE ForLoop1; IMPORT Out; VAR n : INTEGER; BEGIN FOR n := 1 TO 5 DO DEC(n); Out.String("i = "); Out.Int(n, 0); Out.Ln END END ForLoop1.

This code fails to compile due to the attempt to decrement n, which triggers an error. This behavior is expected and thus considered correct.

However, consider the next code snippet:

MODULE ForLimit; IMPORT Out; VAR i, limit : INTEGER; BEGIN limit := 4;

FOR i := 1 TO limit + 1 DO DEC(limit); Out.Int(limit, 0); Out.String(", "); Out.Int(i, 0); Out.Ln END; Out.String(":"); Out.Int(limit, 0); Out.Ln END ForLimit.

This code compiles successfully, but produces unexpected output. The expression limit + 1 should only be evaluated once, but in this case, it appears to be reevaluated with each iteration of the loop, resulting in the following incorrect output:

3, 1 2, 2 1, 3 :1

Expected Behavior

The expected behavior would be for the expression limit + 1 to be evaluated only once, producing the following output:

3, 1 2, 2 1, 3 0, 4 -1, 5 :-1

Reproduction Steps

To reproduce this behavior:

  1. Compile the code using the Oberonc compiler.
  2. Observe that the compiler throws an error on the first example.
  3. Observe that the compiler compiles the code without error on the second example, but produces incorrect output.

Additional Information

Interestingly, compiling the same code with obc yields the correct output for the second example. However, it allows the modification of the control variable within the body of the for loop, which is contrary to the expected behavior. oberonc behaves similarly to Java and C.

β€” Reply to this email directly, view it on GitHub< https://github.com/lboasso/oberonc/issues/33>, or unsubscribe< https://github.com/notifications/unsubscribe-auth/AH3LGZPEAPDUTBNE3QBEDS3YME37DAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43ASLTON2WKOZSGA3DCMBRGI2DGNA>.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

β€” Reply to this email directly, view it on GitHub https://github.com/lboasso/oberonc/issues/33#issuecomment-1872960637, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVJAW2LTUCSHI3QMCURU6LYMFYG5AVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZSHE3DANRTG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

β€” Reply to this email directly, view it on GitHubhttps://github.com/lboasso/oberonc/issues/33#issuecomment-1872972824, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AH3LGZKOMYI3EWHY7WUABH3YMF6QPAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZSHE3TEOBSGQ. You are receiving this because you commented.Message ID: @.***>

geekstakulus commented 8 months ago

Hello @KevinRH and @lboasso,

Firstly, happy new year! I appreciate all the comments and discussions on the topic. I've been reviewing the Oberon 07 Language Report, which, as is characteristic of Niklaus Wirth's writings, leaves room for interpretation. Section 9.8 states that "A for statement specifies the repeated execution of a statement sequence for a given number of times," which I took to mean the same behavior as in Modula-2 and Pascal: "... repeated execution of a statement sequence for a given number of numbers", in my opinion means that it shouldn't change mid course.

I admire Wirth's brilliance, but I also acknowledge his tendency towards laziness and inconsistency. In good engineering practice, specifications are written and adhered to strictly. However, when the implementation deviates from the stated specification due to laziness, it becomes challenging to understand how the system functions.

I stumbled upon the discrepancy regarding the for loop during my study of the Modula-2 compiler. I tested the for loop in the Oberon language using the oberonc compiler, only to find that it behaved like C and Java. And now you tell me that Wirth's RISC compiler behaved in the same way, which show that he hadn't adhered to his own guidelines once again. It appears he implemented the for loop differently in Oberon due to sheer laziness.

Unless there exists another document detailing that the for loop in the RISC compiler should function differently from his other languages, I would expect it to behave as described in the language specifications across all his languages. Interestingly, Wirth had originally removed the for loop from the original Oberon due to oversight.

While I greatly admire Wirth's contributions, I find it difficult to trust his writings as they often don't align with his implementations. This seems to contradict his reputation as a brilliant engineer.

Regarding the experimental features, rather than suggesting a patch, would creating a separate branch be more appropriate? Is this what you intended?

lboasso commented 8 months ago

Happy new Year!

From the latest language report we have a precise definition of the FOR statement:

""" The for statement FOR v := beg TO end BY inc DO S END

is, if inc > 0, equivalent to v := beg; WHILE v <= end DO S; v := v + inc END

and if inc < 0 it is equivalent to v := beg; WHILE v >= end DO S; v := v + inc END """

I'm am traveling so I cannot test this, but if you rewrite your examples as the WHILE statements above you should get the same results as with the FOR implementation in oberonc.

Cheers, Luca

On Tue, Jan 2, 2024, 00:18 Geekstakulus @.***> wrote:

Hello @KevinRH https://github.com/KevinRH and @lboasso https://github.com/lboasso,

Firstly, happy new year! I appreciate all the comments and discussions on the topic. I've been reviewing the Oberon 07 Language Report, which, as is characteristic of Niklaus Wirth's writings, leaves room for interpretation. Section 9.8 states that "A for statement specifies the repeated execution of a statement sequence for a given number of times," which I took to mean the same behavior as in Modula-2 and Pascal: "... repeated execution of a statement sequence for a given number of numbers", in my opinion means that it shouldn't change mid course.

I admire Wirth's brilliance, but I also acknowledge his tendency towards laziness and inconsistency. In good engineering practice, specifications are written and adhered to strictly. However, when the implementation deviates from the stated specification due to laziness, it becomes challenging to understand how the system functions.

I stumbled upon the discrepancy regarding the for loop during my study of the Modula-2 compiler. I tested the for loop in the Oberon language using the oberonc compiler, only to find that it behaved like C and Java. And now you tell me that Wirth's RISC compiler behaved in the same way, which show that he hadn't adhered to his own guidelines once again. It appears he implemented the for loop differently in Oberon due to sheer laziness.

Unless there exists another document detailing that the for loop in the RISC compiler should function differently from his other languages, I would expect it to behave as described in the language specifications across all his languages. Interestingly, Wirth had originally removed the for loop from the original Oberon due to oversight.

While I greatly admire Wirth's contributions, I find it difficult to trust his writings as they often don't align with his implementations. This seems to contradict his reputation as a brilliant engineer.

Regarding the experimental features, rather than suggesting a patch, would creating a separate branch be more appropriate? Is this what you intended?

β€” Reply to this email directly, view it on GitHub https://github.com/lboasso/oberonc/issues/33#issuecomment-1873502978, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVJAW3TYJK2AIXKRYCAAIDYMMY3NAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZTGUYDEOJXHA . You are receiving this because you were mentioned.Message ID: @.***>

geekstakulus commented 8 months ago

Please, improve the following:

Hi, @lboasso !

I have analyzed the specifications of the Oberon 7 programming language before providing my insight. The specs doesn't mention any restrictions on modifying the control variable or stating that the end expression should be fixed. This lack of explicitness leads to ambiguity, which in turn causes the oberonc compiler to flag an error when you attempt to modify the control variable, when the specs says something else.

Let's look at an example by converting the first example to an equivalent while loop as described in the specs:

MODULE WhileLoop1;
    IMPORT Out;
    VAR
        n : INTEGER;
BEGIN
    n := 1;
    WHILE n <= 5 DO
        DEC(n);
        Out.String("i = ");
        Out.Int(n, 0);
        Out.Ln;
        INC(n)
    END
END WhileLoop1.

This code will create an infinite loop because the decrement operation DEC(n) followed by the increment operation INC(n) makes the loop counter n always equal to 1. If you compile and execute the original for loop example with obc, it will present a behaviour equivalent to this while loop, which is correct based on the specs. However, oberonc reports this as an error, and based on the specs, it shouldn't flag an error, because the specs doesn't say anything about not being allowed to change the control variable inside the for loop body or not. The only reason you've done that is because:

  1. It causes an infinite loop, and based on that you opted for a defensive programming approach by forbidding it
  2. Wirth himself implemented it this way in his RISC based compiler

The exact same spec was found in Pascal and Modula-2, yet he opted to make the end expression fixed, but allowed the control variable to be modified inside of the loop body.

Therefore, based on the specs, and here I am referring to semantically equivalence, the correct behaviour should be:

  1. The control variable can be modified and that will produce an infinite loop
  2. The end expression can be modified and that will produce the same behaviour as in C and Java

From an engineering standpoint, I agree with your approach to the first example. However, I reject the ambiguity in the current specs. Consider a scenario where you write a specification for a critical system like an airplane or an automobile. If the implementation deviates from the specifications due to laziness or oversight, it could lead to catastrophic consequences. I believe that Wirth, who is indeed a genius, should have involved real engineers in writing and implementing the specifications, because, despite being a good engineer, his laziness renders a lot of ambiguous documents one cannot rely on.

Therefore, based on the defensive programming approach, let's just close the issue. I agree with the defensive programming approach, and that is how I would implement. However, in the second case, I would implement it as in the obc compiler, or Pascal, Modula-2, Rust and Kotlin.

I will close the issue.

Thanks for your insights!

lboasso commented 8 months ago

I agree with your observations, indeed I toyed with the idea of creating my own programming language using Oberon as stating point. I would change many little details including the FOR statement and most of the syntax...honestly I am not found of uppercase keywords and BEGINs and ENDs :)

On Tue, Jan 2, 2024, 12:38 Geekstakulus @.***> wrote:

Please, improve the following:

Hi, @lboasso https://github.com/lboasso !

I have analyzed the specifications of the Oberon 7 programming language before providing my insight. The specs doesn't mention any restrictions on modifying the control variable or stating that the end expression should be fixed. This lack of explicitness leads to ambiguity, which in turn causes the oberonc compiler to flag an error when you attempt to modify the control variable, when the specs says something else.

Let's look at an example by converting the first example to an equivalent while loop as described in the specs:

MODULE WhileLoop1; IMPORT Out; VAR n : INTEGER; BEGIN FOR n := 1 TO 5 DO DEC(n); Out.String("i = "); Out.Int(n, 0); Out.Ln; INC(n) END END WhileLoop1.

This code will create an infinite loop because the decrement operation DEC(n) followed by the increment operation INC(n) makes the loop counter n always equal to 1. If you compile and execute the original for loop example with obc, it will present a behaviour equivalent to this while loop, which is correct based on the specs. However, oberonc reports this as an error, and based on the specs, it shouldn't flag an error, because the specs doesn't say anything about not being allowed to change the control variable inside the for loop body or not. The only reason you've done that is because:

  1. It causes an infinite loop, and based on that you opted for a defensive programming approach by forbidding it
  2. Wirth himself implemented it this way in his RISC based compiler

The exact same spec was found in Pascal and Modula-2, yet he opted to make the end expression fixed, but allowed the control variable to be modified inside of the loop body.

Therefore, based on the specs, and here I am referring to semantically equivalence, the correct behaviour should be:

  1. The control variable can be modified and that will produce an infinite loop
  2. The end expression can be modified and that will produce the same behaviour as in C and Java

From an engineering standpoint, I agree with your approach to the first example. However, I reject the ambiguity in the current specs. Consider a scenario where you write a specification for a critical system like an airplane or an automobile. If the implementation deviates from the specifications due to laziness or oversight, it could lead to catastrophic consequences. I believe that Wirth, who is indeed a genius, should have involved real engineers in writing and implementing the specifications, because, despite being a good engineer, his laziness renders a lot of ambiguous documents one cannot rely on.

Therefore, based on the defensive programming approach, let's just close the issue. I agree with the defensive programming approach, and that is how I would implement. However, in the second case, I would implement it as in the obc compiler, or Pascal, Modula-2, Rust and Kotlin.

I will close the issue.

Thanks for your insights!

β€” Reply to this email directly, view it on GitHub https://github.com/lboasso/oberonc/issues/33#issuecomment-1873858648, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVJAWZGFRWY3ACRHWVVRMLYMPPSDAVCNFSM6AAAAABBIE5M52VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZTHA2TQNRUHA . You are receiving this because you were mentioned.Message ID: @.***>

geekstakulus commented 8 months ago

While I personally prefer not to use uppercase keywords, I'm able to adapt to this convention. I utilize a custom plugin for NeoVim that transforms all text to uppercase, providing an appealing syntax highlighting feature.

In addition to this, I've conceptualized a programming language inspired by Oberon, but I've yet to dedicate significant time to its development. Instead, I've been engrossed in the task of developing a Modula-2 compiler, based on Wirth's original single-pass compiler. This is where we truly witness the brilliance of Wirth, despite his apparent lack of discipline. Many elements that may initially seem like chaotic or inefficient code were actually ingenious solutions to the limitations of hardware at the time. His compilers are true works of art, demonstrating simplicity and efficiency. The seemingly cryptic variable names were also strategic ways of navigating the hardware constraints. Upon examining the compiler, one can appreciate why he chose to store both identifiers and strings in a single array. This approach, which might seem counter-intuitive, becomes clear upon studying the architecture of the Lilith computer. Despite his occasional laziness and inconsistent documentation, even his books filled with errors, it's crucial to acknowledge that Wirth's genius is undeniable. My admiration for Wirth is quite strong.

My admiration for Dikstra, who was a meticulous engineer, is far stronger, because he paid considerable attention to the details. Both Wirth and Dikstra serve as excellent examples of extraordinary programmers, although Dikstra was far more professional and less inconsistent with his specs vs implementations.

Anyway... thanks once again for this little chat.

geekstakulus commented 8 months ago

Hi again!

I was reading the specs for Modula-2, and surprisingly enough, it is very clear. Here it is:

The expressions before and after the symbol TO define the range through which the so-called control variable (i) progresses. An optional parameter determines the incrementing (decrementing) value. If it is omitted, 1 is assumed as default value. 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.

The specification underscores that "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." However, in his compiler, the control variable isn't restricted from being modified. The specification also ensures that the second expression of the range isn't affected by the repeated statements. This he decided to implement in the compiler.

Anyway... the best thing is to read the specs and the compiler code.