Page 1 of 1

declarations and scope rules

Posted: Sun Oct 22, 2017 4:35 am
by preston
Oberon, how delightful! I'm so pleased to have an alternative to C and C++ for my fun projects.

So, ...
Reading through the spec, in section 4, I find, in the 2nd paragraph, that "No identifier may denote more one object within a given scope."
And that "The scope extends textually from the point of declaration to the end of the block ..."

This sounds different than Pascal, in that Pascal is pretty specific about an inner definition overriding (or shadowing) an outer definition.
I'd interpret the Oberon version as saying "thou shalt not re-use a name inside a scope", even if it's in a nested procedure declaration.
Indeed, I vaguely recall Brinch-Hanson explicitly making a similar point, somewhere, perhaps in Edison?

What do y'all think? Can you find me some text in the language definition that allows names to be re-defined in nested procedures?

Thanks,
Preston

Re: declarations and scope rules

Posted: Thu Oct 26, 2017 12:06 pm
by cfbsoftware
I apologise for the the delay in approving your first post. Any subsequent posts of yours will be accepted immediately.

You can reuse identifiers in nested procedures. However, unlike Pascal and Modula-2, you can only access 'strictly local' or global identifiers from within a nested procedure. Hopefully the following example should illustrate the possibilities:

Code: Select all

MODULE Nested0;

TYPE
  T = ARRAY 10 OF REAL;
VAR
  v: INTEGER;
  vt: T;
  
  PROCEDURE Level1;
    TYPE
      T = ARRAY 20 OF BOOLEAN; (* local type hides global with the same name *)
    VAR
      vt: T; (* local variable hides global with the same name *)

    PROCEDURE Level2;
    VAR
      vt1: T; (* Strictly local variable declared using an intermediate local type is OK *)
    BEGIN
      v := 99;       (* Global variable is OK *)
      vt[0] := 0.0;  (* Error: non-local not accessible *)
      vt1[0] := 0.0  (* Error: Incompatible assignment *) 
    END Level2;
  
  BEGIN (* Level1 *)
    v := 99;      (* Global variable is OK *)
    vt[0] := TRUE (* strictly local level1 variable is OK *)
  END Level1;    
  
  
BEGIN
  v := 99;        (* Global variable is OK *)
  vt[0] := 99.0;
END Nested0.

Re: declarations and scope rules

Posted: Fri Oct 27, 2017 4:13 am
by preston
While I'm confident the compiler allows me to re-use identifiers in nested procedures (I tried it, naturally)
and I'm confident that "Programming in Oberon" discusses it explicitly (page 29),
I was surprised that the language spec seems to skip over the subject entirely.

Thanks,
Preston

Re: declarations and scope rules

Posted: Fri Oct 27, 2017 7:43 am
by cfbsoftware
Your original quote omits some crucial information which totally changes its meaning:
The scope extends textually from the point of the declaration to the end of the block (procedure or module) to which the declaration belongs and hence to which the object is local.
Your expectations of the Language Report may be misguided. Judging by some of the discussions in the various Oberon mailing lists and forums you are not alone in that view.

Prof Wirth's intentions for his Language Report are (and I quote):
I consider such a Report as a defining document. It should be terse and strict. Repetitions must be avoided, as well as statements that can be deduced from other definitions. This had been the "philosophy" of the Algol-60 Report, and I should like to maintain it. It must not be regarded as a tutorial! It can also leave things unsaid, in which case the reader must draw his own conclusions (and avoid unspecified constructs).
Referring to the document Programming in Oberon is what I would have recommended you to do if the report did not convince you. Feel free to ask here if you still have doubts.

Re: declarations and scope rules

Posted: Fri Oct 27, 2017 11:00 pm
by cfbsoftware
I have done some more investigation. Further to my previous post: The other section of the report that is relevant to your question is 10. Procedure Declarations. In the original version of Oberon the visibility of local objects was as it is in Pascal:
In addition to its formal parameters and locally declared objects, the objects declared in the environment of the procedure are also visible in the procedure (with the exception of those objects that have the same name as an object declared locally).
In the current revision of Oberon the visibility is now restricted to strictly local objects:
In addition to its formal parameters and locally declared objects, the objects declared globally are also visible in the procedure.
NOTE: this is how it has been implemented in the Project Oberon and Astrobe Cortex-M Oberon compilers - not as described in Section 11 of Programming in Oberon.

Re: declarations and scope rules

Posted: Sat Oct 28, 2017 9:04 pm
by preston
I guess it depends on how you interpret "the objects declared globally". Conditioned by the rest of the Algol family, I would have said: Global means "not local".
But I guess your interpretation is: Global mean "module level".
While that's plausible, I probably would have gone with tradition and the description in Programming in Oberon.

Preston