<div dir="auto">Probably multiple inheritance was not the right name. It is essentially type extensibility with the ability to extends multiple types at once. This is safe and does not have the the downsides of multiple implementation inheritance, where you share code.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Oct 25, 2020, 12:29 Charles Perkins <<a href="mailto:chuck@kuracali.com">chuck@kuracali.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Andreas and <span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap">Jörg and Lucas,</span><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap"><br></span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap">Thanks for considering how Interfaces can be expressed in Oberon, either natively or through an extension of the language.</span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap"><br></span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap">Andreas, in your scheme can you create separate protocols, for example "Jsonify" with the method ToJSON and a different protocol "Persistify" with the methods "Store" and "Load", and have other records implement one or the other or neither or both?</span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap"><br></span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap">Maybe you can, I have to study your proposal more.</span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap"><br></span></div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap">I'm not actually talking about multiple inheritance here... just composition of behavior.</span></div><div><br></div><div>Regards,</div><div>Chuck</div><div><span style="color:rgb(32,33,36);font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:0.2px;white-space:nowrap"><br></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Oct 25, 2020 at 9:56 AM Andreas Pirklbauer <<a href="mailto:andreas_pirklbauer@yahoo.com" target="_blank" rel="noreferrer">andreas_pirklbauer@yahoo.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> > I have the above code successfully parsing in a fork of Andreas's<br>
> Extended Oberon compiler. I don't have the method table generation code<br>
> working yet. It turns out that the Run-time needs to have symbolic type<br>
> information available, which could be simply loading the smb file alongside<br>
> the rsc file for code that uses interfaces, or it could involve embedding a<br>
> hash of the name and parameters of the type-bound procedure in another<br>
> section of the rsc file. I haven't decided yet.<br>
<br>
Dear Chuck,<br>
<br>
In the proposal put forward earlier in this thread (see example below),<br>
almost no extra code is necessary in the compiler or the runtime, because:<br>
<br>
1. A protocol definition *is* in fact just a regular record definition - the<br>
only difference being that there now is an additional “executable” flag<br>
that indicates that its type-bound procedures cannot be executed.<br>
<br>
2. A protocol implementation *is* is fact just a regular type extension<br>
(of a protocol definition - which this is why the same syntax has been<br>
chosen), where this flag is simply changed such that its type-bound<br>
procedures *can* now be executed.<br>
<br>
That’s all there is to it. Well almost. One also needs to slightly modify<br>
the type checking rules of the compiler such that two protocol<br>
implementations (=type extensions) of the same protocol definition<br>
(=the base type) are in fact assignment-compatible (unlike two<br>
“regular” record extensions of the same base type which are not).<br>
<br>
And of course the "non-executable” flag must be correctly propagated<br>
across symbol and object files as well.<br>
<br>
-ap<br>
<br>
<br>
MODULE TextProtocol; (*protocol definition*)<br>
TYPE Text* = POINTER TO TextDesc;<br>
TextDesc* = RECORD data*: (*text data*) END ;<br>
PROCEDURE (t: Text) Insert* (string: ARRAY OF CHAR; pos: LONGINT);<br>
PROCEDURE (t: Text) Delete* (from, to: LONGINT);<br>
PROCEDURE (t: Text) Length* (): LONGINT;<br>
END TextProtocol;<br>
<br>
MODULE Text1; (*one implementation of the Text protocol*)<br>
IMPORT TextProtocol;<br>
TYPE Text* = POINTER TO TextDesc;<br>
TextDesc* = RECORD (TextProtocol.TextDesc) END ; (*this means: “implements TextProtocol.TextDesc"*)<br>
<br>
PROCEDURE (t: Text) Insert* (string: ARRAY OF CHAR; pos: LONGINT);<br>
BEGIN (*implementation of Insert*)<br>
END Insert;<br>
<br>
PROCEDURE (t: Text) Delete* (from, to: LONGINT);<br>
BEGIN (*implementation of Delete*)<br>
END Delete;<br>
<br>
PROCEDURE (t: Text) Length* (): LONGINT;<br>
BEGIN (*implementation of Length*)<br>
END Insert;<br>
END Text1;<br>
<br>
<br>
MODULE Text2; (*another implementation of the Text protocol*)<br>
IMPORT TextProtocol;<br>
TYPE Text* = POINTER TO TextDesc;<br>
TextDesc* = RECORD (TextProtocol.TextDesc) END ; (*this means: “implements TextProtocol.TextDesc"*)<br>
<br>
PROCEDURE (t: Text) Insert* (string: ARRAY OF CHAR; pos: LONGINT);<br>
BEGIN (*implementation of Insert*)<br>
END Insert;<br>
<br>
PROCEDURE (t: Text) Delete* (from, to: LONGINT);<br>
BEGIN (*implementation of Delete*)<br>
END Delete;<br>
<br>
PROCEDURE (t: Text) Length* (): LONGINT;<br>
BEGIN (*implementation of Length*)<br>
END Insert;<br>
END Text2;<br>
<br>
<br>
--<br>
<a href="mailto:Oberon@lists.inf.ethz.ch" target="_blank" rel="noreferrer">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems<br>
<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" rel="noreferrer noreferrer" target="_blank">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><br>
</blockquote></div>
--<br>
<a href="mailto:Oberon@lists.inf.ethz.ch" target="_blank" rel="noreferrer">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems<br>
<a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" rel="noreferrer noreferrer" target="_blank">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><br>
</blockquote></div>