<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Felix,</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">(writing this on iphone while travelling, pls apologize typos)</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">That is absolutely correct. The "old" B is no longer there, but there are still elements created by the "old" B in the data structure rooted in base module A.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">I would say this:</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">1) Module C *should* only be able to remove elements of the "new" B</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">2) The fact the elements from the "old" B are still around is a problem that should only concern the "old" B</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">3) In Experimental Oberon, the module block of the "old" B is still around in memory (i.e. is not released) *precisely* because there are still type references (type tags) in the base module A pointing to type descriptors located in the module block if the "old" B. so the code of the "old" B is also still around, even though a "new" B has been loaded in the meantime and is now *the* one B that is showing up in the module list displayed by System.ShowModules (note that the "old" B is also shown, but with an asterisk).</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">4) So how can the elements of the "old" B be removed? The answer is they can't. It's a programming error. However, the base module A itself *should* be able to remove *any* element created by either the "old" B or the "new" B. I have actually played with this a little bit, with A = module Viewers. Viewers.Close closes any viewer (= A.Close) and removes it from the data structure rooted in Viewers (=A). In doing so it might for example call a "close" method that could be an installed procedure that is different for each extension. In THAT case, module A would call the exact right "close" method (a kind if finalizer but not for a module, but an object) - namely the "old" one for the "old" B, and the "new" one for the "new" B.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature"> So it *can* be handled, but one has to program for it. True.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Will get back to you once I'm in front of a computer.. will run your code through Experimental Oberon. It's worth pondering this example some more..</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Another comment: Have you thought about a generic persistence mechanism: B "persists" an object so that it is now in fact "owned" by A (think: you download a pdf document in your mail client, then tap "Save to Documents" - now the Documents app "takes over" and now owns that pdf document, and the mail app can be deleted).</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">I want to experiment with that in Experimental Oberon and realize exactly that (in a generic way).</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Andreas</div><div id="AppleMailSignature"><br><br>Sent from my iPhone</div><div><br>On 17 Nov 2016, at 16:36, Felix Friedrich <<a href="mailto:felix.friedrich@inf.ethz.ch">felix.friedrich@inf.ethz.ch</a>> wrote:<br><br></div><blockquote type="cite"><div>
  
    <meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
  
  
    <div class="moz-cite-prefix">Andreas<br>
      <br>
      I imagine the following, admittedly artificial, setup:<br>
      <br>
      MODULE A contains a list L of some R0 = POINTER TO RECORD ... END
      <br>
      For example A provides base type and repositories of geometric
      figures.<br>
      <br>
      MODULE B imports A and declares R1 = POINTER TO RECORD (A.R0) ..
      END; <br>
      For example R1 describes a circle.<br>
      <br>
      MODULE C traverses the list of A identifying every B.R1 element
      with a type test:<br>
      IF element IS R1 THEN (* e.g. remove it from the list A.L *) END;
      <br>
      For example C constitutes a graphics program providing a mechanism
      to remove all circles from a plot.<br>
      <br>
      The problem is that if B is unloaded after some circles had been
      deposited in A.L and if B is loaded again and only then C is
      becoming active, it will only remove elements from the new B but
      not of the older B: there will still be circles in the plot.<br>
      <br>
      <br>
      Minimal Test code:<br>
      <br>
      MODULE A;<br>
      TYPE R* = POINTER TO RECORD END;<br>
      VAR r*: R;<br>
      END A.<br>
      <br>
      MODULE B;<br>
      IMPORT A;<br>
      TYPE R* = POINTER TO RECORD(A.R) END;<br>
      VAR r: R;<br>
      BEGIN  <br>
          NEW(r);<br>
          IF A.r = NIL THEN<br>
              A.r := r;<br>
          END;<br>
      END B.<br>
      <br>
      MODULE C;<br>
      IMPORT A,B;<br>
      BEGIN<br>
          IF A.r IS B.R THEN A.r := NIL END; (* problem: type test
      refers to "new" version of B.R while an instance of an old version
      of B.R is still existing. *)<br>
          ASSERT(A.r = NIL);  <br>
      END C.<br>
      <br>
      Load Module C.<br>
      System.Free C ~<br>
      Load Module C. (--> TRAP)<br>
      <br>
      Rgds<br>
      Felix<br>
      <br>
      <br>
    </div>
    <blockquote cite="mid:820376940.2296230.1478944376342@mail.yahoo.com" type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div style="color:#000; background-color:#fff;
        font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande,
        sans-serif;font-size:13px">
        <div id="yui_3_16_0_ym19_1_1478930367016_11861">Felix,</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">that
          appears to be a solvable problem though. Two comments:</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">(i) In
          order to keep "old" types and methods around, it suffices to
          keep older versions of a module block (containing both its
          type descriptors and its procedures) around in main memory, as
          long as there are references to them from the remaining part
          of the system.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">(ii)
          Even if an "old" version of a module passes a pointer around
          and that pointer suddenly ends up in a newer version (of
          potentially the same module), it is not really a problem (I
          think, but happy to be proven wrong) - so long as the "old"
          type descriptors and methods are still available in memory.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">Note
          that "old" methods will of course also access the "old" record
          and the "old" type descriptor for that record type, so there
          doesn't seem to be problem in principle. That of course needs
          to be taken with a grain of salt, just like one needs to take
          module interfaces with a grain of salt. If the newer version
          of a module doesn't actually change the module *interface*
          (i.e. meaning that clients do not need to be recompiled), but
          significantly changes the semantics of its implementation,
          there may be issues. All that is really guaranteed is that the
          module *interface* doesn't change - so even with modules, it
          is the programmer's responsibility that the *semantics*
          between multiple versions are "consistent". I'd say it's the
          same with records and methods.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">PS: I
          have implemented (i), but have not tested an example for (ii)
          yet. So if someone supplied a short test program for that in
          this forum, I'd be happy to test and then report on it.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr">Andreas</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11861" dir="ltr"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11937">-------------------------------------------------------------------------------------------</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11937" dir="ltr">From:
          Felix Friedrich felix.friedrich at <a href="http://inf.ethz.ch">inf.ethz.ch</a> </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11938">Tue Sep 27
          19:11:59 CEST 2016</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11942"><br>
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11964">> But this
          does not solve other problems coming from the possible </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11965">> coexistence
          of an old and new version of a module. If the old module </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11966">> survives,
          pointers could be passed around to new modules compromising </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11967">> the type
          system.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11968"><br id="yui_3_16_0_ym19_1_1478930367016_11969">
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11970">> I think
          that any kind of upcall, be it via procedure variables or via </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11971">> object
          methods does not go well with module unloading.</div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11972"><br id="yui_3_16_0_ym19_1_1478930367016_11973">
        </div>
        <div id="yui_3_16_0_ym19_1_1478930367016_11974">> Felix</div>
        <div dir="ltr" id="yui_3_16_0_ym19_1_1478930367016_11975"><br id="yui_3_16_0_ym19_1_1478930367016_11976">
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">--
<a class="moz-txt-link-abbreviated" href="mailto:Oberon@lists.inf.ethz.ch">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems
<a class="moz-txt-link-freetext" href="https://lists.inf.ethz.ch/mailman/listinfo/oberon">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a>
</pre>
    </blockquote>
    <p><br>
    </p>
  

</div></blockquote></body></html>