[net.lang] declarations and nested blocks

barmar@mit-eddie.UUCP (Barry Margolin) (12/19/83)

<this line intentionally left non-blank>

There is a feature of PL/I and Algol which is used in most of their
descendents which is both useful and painful.  I am referring to the
fact that the scope of variables includes nested procedures.  It allows
one to write simpler (though less clear) code, but it also permits one
to write incorrect code pretty easily.  This problem is exemplified in
the following fragment:

	do index = 1 to 10;
	     call subr (array (index));
	end;

	subr: procedure (thing);
	      ...
	      do index = 1 to 5;
	      ...
	      end;
	end subr;

Since the programmer forgot to declare a local "index" variable in subr
he ends up with an infinite loop, since index will never reach 10; it
will be set to 5 after each iteration.

I'm surprised that Ada(tm) does not require some explicit statement to
allow you to inherit from an outer block.  Why is this feature
propogated to all new languages, with hardly any change?
-- 
			Barry Margolin
			ARPA: barmar@MIT-Multics
			UUCP: ..!genrad!mit-eddie!barmar

jonab@sdcrdcf.UUCP (Jonathan Biggar) (12/20/83)

In article <1072@mit-eddie.UUCP> barmar@mit-eddie.UUCP (Barry Margolin)
writes:
>
>There is a feature of PL/I and Algol which is used in most of their
>descendents which is both useful and painful.  I am referring to the
>fact that the scope of variables includes nested procedures.  It allows
>one to write simpler (though less clear) code, but it also permits one
>to write incorrect code pretty easily.  This problem is exemplified in
>the following fragment:
>
>	do index = 1 to 10;
>	     call subr (array (index));
>	end;
>
>	subr: procedure (thing);
>	      ...
>	      do index = 1 to 5;
>	      ...
>	      end;
>	end subr;
>
>Since the programmer forgot to declare a local "index" variable in subr
>he ends up with an infinite loop, since index will never reach 10; it
>will be set to 5 after each iteration.
>
>I'm surprised that Ada(tm) does not require some explicit statement to
>allow you to inherit from an outer block.  Why is this feature
>propogated to all new languages, with hardly any change?

Ada(tm) does not have this problem, because the index variable in a
for loop is implicitly declared to be the type of the range it varies
over:

	loop1: for i in 1..10 loop
		loop2: for i in 1..5 loop
			...
		end loop loop2;
	end loop loop1;

loop1.i is not the same variable as loop2.i, therefore there can
be no infinite loop.  (Note that the code inside both loops can
reference both variables as loop1.i and loop2.i.)
-- 
Jon Biggar
{allegra,burdvax,cbosgd,hplabs,ihnp4,sdccsu3,trw-unix}!sdcrdcf!jonab

ka@hou3c.UUCP (Kenneth Almquist) (12/21/83)

I agree.  The Algol-like procedure nesting is in my view one of the big
deficiencies of Pascal.  Simula and various Pascal descendents provide
for explicit importing of global variables, and it's surprizing that the
Ada designers didn't provide it.  Fortunately in Ada you can get around
the problem by placing procedures in separate packages.
				Kenneth Almquist

mdash@mh3bc1.UUCP (M.D.Scheer) (12/22/83)

Of course, Ada for loop iterators are implicitly declared, but
this does not solve the general problem of unintenionally modifying
variables inherited from outer scopes.

One solution is to use naming conventions like P_X (subject this
construct to the lexical restrictions of your favorite programming
language) for the variable X declared in procedure P.  This would
solve the majority of >accidents< arising from implicit inheritance
in nested scopes.

Many of the >problems< arising in nested scopes are not accidents,
though.  Simple nesting is simply an inadequate form of program organization
and makes certain problems unavoidable.  For a nice discussion of the
problems of nested organization, see the paper by Clarke, Wileden,
and Wolf, "Nesting in Ada Programs is for the Birds," SIGPLAN Notices,
v.15, #11, November 1980.