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.