<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><pre class="" style="white-space: pre-wrap; background-color: rgb(255, 255, 255);">EDIT: An even shorter version of module M shows how the *local* procedure Q is *directly* assigned to a *global* variable M.proc (by procedure P):</pre><pre class="" style="white-space: pre-wrap; background-color: rgb(255, 255, 255);"><br class=""></pre><pre class="" style="background-color: rgb(255, 255, 255);"><span style="white-space: pre-wrap;" class="">MODULE M;<br class="">  IMPORT Texts, Oberon;<br class=""><br class="">  TYPE PROC* = PROCEDURE;<br class="">  VAR proc*: PROC;<br class="">    W: Texts.Writer;<br class=""><br class="">  PROCEDURE P ();<br class=""><br class="">    PROCEDURE Q;<br class="">    BEGIN Texts.WriteString(W, "Q executing"); Texts.Append(Oberon.Log, W.buf)<br class="">    END Q;<br class=""><br class="">  BEGIN proc := Q<br class="">  END P;<br class=""><br class="">BEGIN Texts.OpenWriter(W); P()<br class="">END M.<br class=""><br class=""></span></pre><pre class="" style="white-space: pre-wrap; background-color: rgb(255, 255, 255);">Andreas</pre><pre class="" style="white-space: pre-wrap; background-color: rgb(255, 255, 255);"><br class=""></pre><div><blockquote type="cite" class=""><div class="">On 28 Sep 2017, at 20:26, Andreas Pirklbauer <<a href="mailto:andreas_pirklbauer@yahoo.com" class="">andreas_pirklbauer@yahoo.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">Wojtek,</pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">sure, this is possible - below is a slightly modified version. Compile M and N, then activate N.Run.</pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class="">MODULE M;<br class="">  IMPORT Texts, Oberon;<br class=""><br class="">  TYPE PROC* = PROCEDURE;<br class="">  VAR proc*: PROC;<br class="">    W: Texts.Writer;<br class=""><br class="">  PROCEDURE P () : PROC;<br class="">    VAR p: PROCEDURE;<br class=""><br class="">    PROCEDURE Q;<br class="">    BEGIN Texts.WriteString(W, "Q executing"); Texts.Append(Oberon.Log, W.buf)<br class="">    END Q;<br class=""><br class="">  BEGIN p := Q;<br class="">    RETURN p<br class="">  END P;<br class=""><br class="">BEGIN Texts.OpenWriter(W); proc := P()<br class="">END M.</span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class="">MODULE N;</span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class="">  IMPORT M;<br class=""><br class="">  PROCEDURE Run*;<br class="">  BEGIN M.proc()<br class="">  END Run;<br class=""><br class="">END N.</span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></pre><pre style="background-color: rgb(255, 255, 255);" class=""><pre class=""><span style="white-space: pre-wrap;" class="">Local procedures are in fact almost identical to global procedures - they are compiled just like any (global) procedure, they have a fixed static starting address within the module block (where they are stored, just like global procedures). Therefore, they can of course also be assigned to variables and/or returned as the result of a function procedure, as shown in the above example.</span></pre><pre class=""><pre class=""><div class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></div><div class=""><span style="white-space: pre-wrap;" class="">The only difference to global procedures is that it can only be *accessed by name* (i.e. in the source code) from the enclosing scope. For example, the local procedure Q can only *accessed by name* from the enclosing procedure P - i.e. only P can reference Q by name: it might of course call Q directly, but it can also assign Q to a local or global variable. Such an assignment is perfectly legitimate (recall that internally simply the address of Q is copied).</span></div></pre></pre><pre class=""><div class=""><span style="white-space: pre-wrap;" class=""><br class=""></span></div><div class=""><span style="white-space: pre-wrap;" class="">So the fact that a local procedure Q can only be *accessed by name* from the enclosing scope does NOT mean that it somehow “disappears” once the enclosing procedure P has been executed. In other words, local procedures do NOT behave like local variables, which are allocated on the stack and indeed disappear once the procedure declaring them has been executed. By contrast, “local" procedures don’t go away, once the enclosing procedure has been executed. They are still there, it’s just that they can be accessed by their name only when the enclosing procedure executes.</span></div><div class=""><br class=""></div></pre><div class=""><span style="white-space: pre-wrap;" class="">Andreas</span></div></pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""><br class=""></pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">---------------------------</pre><pre style="background-color: rgb(255, 255, 255);" class=""><span style="white-space: pre-wrap;" class="">Thu Sep 28 19:06:44 CEST 2017 Skulski, Wojciech skulski at <a href="http://pas.rochester.edu/" class="">pas.rochester.edu</a> wrote:</span></pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">Andreas:

  is the following code correct? If so, can another module import M and call M.proc()? What is the intent, if it is possible?

MODULE M;
TYPE PROC* = PROCEDURE;
VAR proc*: PROC;

PROCEDURE P () : PROC;
VAR p: PROCEDURE;

      PROCEDURE Q; BEGIN END Q;

BEGIN p := Q
   RETURN p
END P;
END M.


________________________________________
From: Oberon [<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">oberon-bounces at lists.inf.ethz.ch</a>] on behalf of Andreas Pirklbauer [<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">andreas_pirklbauer at yahoo.com</a>]
Sent: Thursday, September 28, 2017 12:57 PM
To: ETH Oberon and related systems
Subject: [Oberon]  Procedure variables and local procedures

Addendum: Another way to read the sentence “P must not be declared local to ANOTHER procedure” is that in fact “P may be declared local to the SAME procedure”. This is the case in the example below. Either way, the assignment to procedure variables is not restricted to globally defined procedures.

AP


On 28 Sep 2017, at 18:11, Andreas Pirklbauer <<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">andreas_pirklbauer at yahoo.com</a><mailto:<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">andreas_pirklbauer at yahoo.com</a>>> wrote:


Note that even though the Oberon language report of Oberon-07 still states that “If a procedure P is assigned to a procedure variable of type T [...]. P must not be declared local to another procedure”, in the current implementation of Oberon-07, this restriction is not actually checked - at least not in the case when the procedure variable to which a local procedure is assigned is itself declared locally in the same scope, as in the following example:

    MODULE M;

    PROCEDURE P;
      VAR p: PROCEDURE;

      PROCEDURE Q; BEGIN END Q;

    BEGIN p := Q
    END P;
  END M.


which compiles correctly under Oberon 2013 without an error message.

AP

--------------------------------------------------------------------------

August Karlstrom <a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">fusionfile at gmail.com</a><mailto:<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" class="">fusionfile at gmail.com</a>> Thu Sep 18 12:14:29 CEST 2017

In the latest revision of the Oberon language, access to identifiers in
intermediate scopes is denied. Doesn't this imply that the restriction
that only globally defined procedures can be assigned to procedure
variables, is the unnecessary?

-- August
</pre></div><div class=""><br class=""></div></div></div></blockquote></div><br class=""></body></html>