Variable declaration reset: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Visual Basic .NET)
(Added PL/M)
Line 78: Line 78:
Like the first/unchanged JavaScript example, under pwa/p2js there is no output (at least as things currently stand)<br>
Like the first/unchanged JavaScript example, under pwa/p2js there is no output (at least as things currently stand)<br>
Obviously you can achieve consistent results by manually hoisting the declaration of prev to before/outside the loop.
Obviously you can achieve consistent results by manually hoisting the declaration of prev to before/outside the loop.

=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
Although PL/M has block scope, all variables are static, so PREV retains its value between iterations of the loop.<br>
Note the extra DO which is necessary to introduce a new scope as declarations are not allowed in a DO loop.
<lang pli>100H:

/* CP/M BDOS SYSTEM CALL */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;END;
/* CONSOLE OUTPUT ROUTINES */
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PR$NL: PROCEDURE; CALL PR$STRING( .( 0DH, 0AH, '$' ) ); END;
PR$NUMBER: PROCEDURE( N );
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR( 6 ) BYTE INITIAL( '.....$' ), W BYTE;
N$STR( W := LAST( N$STR ) - 1 ) = '0' + ( ( V := N ) MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
CALL PR$STRING( .N$STR( W ) );
END PR$NUMBER;

/* TASK */
DECLARE S( 6 ) BYTE INITIAL( 1, 2, 2, 3, 4, 4, 5 );
DECLARE I BYTE;
DO I = 0 TO LAST( S );
DO;
DECLARE ( CURR, PREV ) BYTE;
CURR = S( I );
IF I > 1 AND CURR = PREV THEN DO;
CALL PR$NUMBER( I );
CALL PR$NL;
END;
PREV = CURR;
END;
END;

EOF</lang>
{{out}}
<pre>
2
5
</pre>


=={{header|Visual Basic .NET}}==
=={{header|Visual Basic .NET}}==

Revision as of 23:45, 15 April 2022

Variable declaration reset is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A decidely non-challenging task to highlight a potential difference between programming languages.

Using a straightforward longhand loop as in the JavaScript and Phix examples below, show the locations of elements which are identical to the immediately preceding element in {1,2,2,3,4,4,5}. The (non-blank) results may be 2,5 for zero-based or 3,6 if one-based.
The purpose is to determine whether variable declaration (in block scope) resets the contents on every iteration.
If your programming language does not support block scope (eg assembly) it should be omitted from this task.

ALGOL 68

Algol 68n should produce no output as each iteration of the loop has a separate instance of the variables.
The Algol 68 euivalent of the Phix program is as below, whether this works as expected depends on how the implementation treats uninitialised variables... <lang algol68>BEGIN

   []INT s = ( 1, 2, 2, 3, 4, 4, 5 );
   FOR i TO ( UPB s -LWB s ) + 1 DO
       INT curr := s[ i ], prev;
       IF IF i > 1 THEN curr = prev ELSE FALSE FI THEN
           print( ( i, newline ) )
       FI;
       prev := curr
   OD

END</lang>

Output:

with Algol 68G

5             IF i > 1 AND curr = prev THEN
                                  1
a68g-2.8.3: runtime error: 1: attempt to use an uninitialised INT value (detected in VOID conditional-clause starting at "IF" in this line).

with Rutgers Algol 68:
No output.

JavaScript

<lang javascript><!DOCTYPE html> <html lang="en" >

<head>
 <meta charset="utf-8"/>
 <meta name="viewport" content="width=device-width, initial-scale=1"/>
 <title>variable declaration reset</title>
</head>
<body>
 <script>

"use strict"; let s = [1, 2, 2, 3, 4, 4, 5]; for (let i=0; i<7; i+=1) {

   let curr = s[i], prev;
   if (i>1 && (curr===prev)) {
       console.log(i);
   }
   prev = curr;

}

 </script>
</body>

</html></lang> No output
Manually moving the declaration of prev to before the loop, or changing the third "let" to "var" (causes legacy hoisting and) gives:

Output:
2
5

Phix

with javascript_semantics
sequence s = {1,2,2,3,4,4,5}
for i=1 to length(s) do
    integer curr = s[i], prev
    if i>1 and curr=prev then
        ?i
    end if
    prev = curr
end for
Output:
3
6

Like the first/unchanged JavaScript example, under pwa/p2js there is no output (at least as things currently stand)
Obviously you can achieve consistent results by manually hoisting the declaration of prev to before/outside the loop.

PL/M

Works with: 8080 PL/M Compiler

... under CP/M (or an emulator)

Although PL/M has block scope, all variables are static, so PREV retains its value between iterations of the loop.
Note the extra DO which is necessary to introduce a new scope as declarations are not allowed in a DO loop. <lang pli>100H:

  /* CP/M BDOS SYSTEM CALL */
  BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;END;
  /* CONSOLE OUTPUT ROUTINES */
  PR$CHAR:   PROCEDURE( C ); DECLARE C BYTE;    CALL BDOS( 2, C ); END;
  PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
  PR$NL:     PROCEDURE; CALL PR$STRING( .( 0DH, 0AH, '$' ) );      END;
  PR$NUMBER: PROCEDURE( N );
     DECLARE N ADDRESS;
     DECLARE V ADDRESS, N$STR( 6 ) BYTE INITIAL( '.....$' ), W BYTE;
     N$STR( W := LAST( N$STR ) - 1 ) = '0' + ( ( V := N ) MOD 10 );
     DO WHILE( ( V := V / 10 ) > 0 );
        N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
     END;
     CALL PR$STRING( .N$STR( W ) );
  END PR$NUMBER;
  /* TASK */
  DECLARE S( 6 ) BYTE INITIAL( 1, 2, 2, 3, 4, 4, 5 );
  DECLARE I BYTE;
  DO I = 0 TO LAST( S );
     DO;
        DECLARE ( CURR, PREV ) BYTE;
        CURR = S( I );
        IF I > 1 AND CURR = PREV THEN DO;
           CALL PR$NUMBER( I );
           CALL PR$NL;
        END;
        PREV = CURR;
     END;
  END;

EOF</lang>

Output:
2
5

Visual Basic .NET

<lang vbnet>Option Strict On Option Explicit On

Imports System.IO

Module vMain

   Public Sub Main
       Dim s As Integer() = New Integer(){1, 2, 2, 3, 4, 4, 5}
       For i As Integer = 0 To Ubound(s)
           Dim curr As Integer = s(i)
           Dim prev As Integer
           If i > 1 AndAlso curr = prev Then
                 Console.Out.WriteLine(i)
           End If
           prev = curr
       Next i
   End Sub

End Module</lang>

Output:
2
5