<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><pre id="yui_3_16_0_ym19_1_1475307863727_34361">Chris, Joerg:</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">that is exactly the problem: assigning a procedure of a *client* module to a procedure variable of an *imported* module, and then unloading the client module - leaving the procedure variable in the imported module dangling.</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">Assigning a procedure of a client module to a variable of an imported "base" module is in fact the standard way the Oberon system itself employs procedure variables to implement the viewer system in an object-oriented style.</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">For example, module TextFrames (the client) installs a handler (procedure TextFrames.Handle) in the field F.handle of text frame F (see TextFrames.NewText and TextFrames.Open for the details), where the record field F.handle is declared as a procedure variable in the "base" module Viewers (see Viewers.ViewerDesc), which also manages the viewer data structure (see procedure Viewers.Open). </pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">Except that of course in the case of the Oberon system, the "client" module TextFrames *never* gets unloaded, so this is not a problem there. Thus, the burden is on the user to make sure that such modules never get unloaded.</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">It is of course possible to implement a "procedure variable" counter - in analogy to the "module counter" employed in Oberon: each time an assignment to a procedure variable is made, the counter gets increased. But that would require changing the code generator compiler for assignments, and the module loader (Modules.Load) and unloader (Modules.Free). But I would refrain from introducing such complexity to the compiler and runtime system.</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34361">Andreas</pre><div id="yui_3_16_0_ym19_1_1475307863727_34155"><br></div><div id="yui_3_16_0_ym19_1_1475307863727_34286"><b style="font-family: -webkit-standard;" id="yui_3_16_0_ym19_1_1475307863727_34287">Chris Burrows</b><span style="font-family: -webkit-standard; font-size: medium;" id="yui_3_16_0_ym19_1_1475307863727_34288"> </span><a href="mailto:oberon%40lists.inf.ethz.ch?Subject=Re:%20Re%3A%20%5BOberon%5D%20Oberon%20for%20a%20C%2B%2B%20user.&In-Reply-To=%3C000a01d21ba8%24b97dc9d0%242c795d70%24%40cfbsoftware.com%3E" title="[Oberon] Oberon for a C++ user." style="font-family: -webkit-standard; background-color: rgb(255, 255, 255);" id="yui_3_16_0_ym19_1_1475307863727_34289" title-off="">chris at cfbsoftware.com </a><br style="font-family: -webkit-standard;" id="yui_3_16_0_ym19_1_1475307863727_34290"></div><br><hr style="font-family: -webkit-standard;" id="yui_3_16_0_ym19_1_1475307863727_34305"><pre id="yui_3_16_0_ym19_1_1475307863727_34306">> Joerg,
>
> OK - you may well be onto something here but it is incomplete as it is. Something has to</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34306">> import Square so that the module body is executed, or you need an exported procedure in</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34306">> Square that is called from the OS. </pre><pre id="yui_3_16_0_ym19_1_1475307863727_34306">>
> Note: there are a couple of semicolons missing and Init must be exported.</pre><pre id="yui_3_16_0_ym19_1_1475307863727_34306">>
> Chris.

><i id="yui_3_16_0_ym19_1_1475307863727_34307"> -----Original Message-----
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34308"> From: Jörg Straube [mailto:<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" id="yui_3_16_0_ym19_1_1475307863727_34309">joerg.straube at iaeth.ch</a>]
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34310"> Sent: Saturday, 1 October 2016 2:22 PM
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34311"> To: <a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" id="yui_3_16_0_ym19_1_1475307863727_34312">chris at cfbsoftware.com</a>; ETH Oberon and related systems
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34313"> Subject: Re: [Oberon] Oberon for a C++ user.
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34314"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34315"> Chris
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34316"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34317"> Here a possble example that might cause issues:
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34318"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34319"> MODULE Figure;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34320"> TYPE
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34321">   DrawProc = PROCEDURE;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34322">   Figure = POINTER TO FigureDesc;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34323">   FigureDesc = RECORD
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34324">     next: Figure;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34325">     draw: DrawProc
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34326">   END;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34327"> VAR list: Figure;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34328"> PROCEDURE Init(d: DrawProc)
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34329">   VAR f: Figure;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34330">   BEGIN
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34331">     NEW(f); f.next := list; list := f;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34332">     f.draw := d
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34333">   END Init;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34334"> BEGIN list:= NIL END Figure.
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34335"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34336"> MODULE Square;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34337"> IMPORT Figure;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34338"> PROCEDURE DrawSquare;
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34339">   BEGIN (* do what ever you
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34340">     need to do to draw a square *)
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34341">   END DrawSquare
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34342"> BEGIN
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34343">   Figure.Init(DrawSquare)
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34344"> END Square.
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34345"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34346"> Now you could run Square and unload Square. The list in Figure has a
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34347"> reference to unloaded code.
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34348"> 
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34349"> J rg
</i>><i id="yui_3_16_0_ym19_1_1475307863727_34350"> </i></pre></div></body></html>