Open mw66 opened 3 years ago
https://forum.dlang.org/thread/obqthozmxwzhvrafothw@forum.dlang.org
Suppose a person who has both US & UK residence, travel to Paris, and feel ill need to withdraw some money and see a doctor:
1) the person can only have 1 (one) name 2) the person has 3 addresses: one in US, one in UK, and a temp hotel address in Paris 3) the person's bank account that can only be read by the bank 4) the person's health info that can only be read by doctor
I will show the Eiffel program, with the compiler ensures all these constraints:
https://github.com/mingwugmail/dlang_tour/tree/master/eiffel/visitor
https://forum.dlang.org/post/pidvdadmyqceqqkdfkcv@forum.dlang.org
On Monday, 28 September 2020 at 19:41:07 UTC, H. S. Teoh wrote:
On Mon, Sep 28, 2020 at 06:56:40PM +0000, mw via Digitalmars-d wrote: [...]
It's all about resolve name clashing:
alias
means synonyms; let's just borrow from Eiffel, instead of re-invent the wheels: the main concepts to solve multiple inheritance are these 5 keywords:https://www.eiffel.org/doc/eiffel/Eiffel_programming_language_reserved_words
rename
export
undefine
redefine
-- D's overrideselect
I don't know Eiffel; could you enlighten me as to how it solves the following instance of the diamond problem?
struct Resource { this(...) { acquireResource(); } ~this() { releaseResource(); } }
class A { Resource x; }
class B : A { ... }
class C : A { ... }
class D : B, C { // Should D have one instance of A.x, or two instances // of A.x? (Putting aside the question of naming for the // time being -- let's pretend we have a way of // addressing x somehow in either case.) }
I can see some situations for which you want two distinct instances of A.x (there should be two distinct resources acquired by D), and some other situations for which you want them to be the same (the same resource should be shared by B and C). How does Eiffel cater to both cases?
The Resource A.x in your example is what I have shown in my example PERSON.addr and PERSON.name here:
https://forum.dlang.org/thread/obqthozmxwzhvrafothw@forum.dlang.org
1) In Eiffel, by default the attribute is shared/joined, meaning in your above code as it its, there is only 1 x
in D; and that's the PERSON.name in my example (no special treatment, it's just joined in D).
2) If the application do want separate instances of one attribute, PERSON.addr in my example, then use rename
/ select
to choose the one the programmer wanted semantics in mind. So in this case, your example is:
class B : A {...}
class C : A {...}
// let's suppose the application's semantics want to use C.x, but still keep B.x
class D1 : B(rename x as bx) // (rename ...) is my invented Eiffel syntax in D
, C(select x) { // (select ...) is my invented Eiffel syntax in D
...
}
// let's suppose the application's semantics want to use B.x, but still keep C.x
class D2 : B(select x)
, C(rename x as cx) {
...
}
// let's suppose the application's semantics want to use B.x, but remove C.x
class D3 : B(select x)
, C(undefine x) {
...
}
// let's suppose the application's semantics want to use C.x, but remove B.x
class D4 : B(undefine x)
, C(select x) {
...
}
// let's suppose the application's semantics want to remove both B.x and C.x
class D5 : B(undefine x)
, C(undefine x) {
redefine x; // need to redefine x
}
// let's suppose the application's semantics want to keep both B.x and C.x
class D6 : B(rename x as bx)
, C(rename x as cx) {
redefine x; // need to redefine x
}
... as you can see, all different application semantics can be specified by the programmer.
Please check my previous PERSON.addr example more carefully.
PERSON.addr UK_RESIDENT(: PERSON).addr US_RESIDENT(: PERSON).addr VISITOR(: UK_RESIDENT, US_RESIDENT).addr
https://forum.dlang.org/post/obqthozmxwzhvrafothw@forum.dlang.org
This is the idea from the discussion:
https://forum.dlang.org/post/ltkcbcwtgrxceesnnxqk@forum.dlang.org
Background:
Although D intendeds to have single-inheritance with multiple interfaces, but the multiple inheritance problems have crept into D already, because of the introduction of
mixin
and (multiple-)alias this
, which caused many unsolvable troubles in current D.Actually the diamond problem is a solved problem by Eiffel language, which won the 2006 ACM Software System Award:
https://en.wikipedia.org/wiki/ACM_Software_System_Award
And I showed the concrete example here: https://forum.dlang.org/thread/obqthozmxwzhvrafothw@forum.dlang.org
https://forum.dlang.org/post/rb4seo$bfm$1@digitalmars.com The two hallmarks of Eiffel, is design-by-contract and multiple inheritance, which is known in academics (in my former life).
it's a pity that
D only picked design-by-contract from Eiffel, but throw away multiple inheritance,
... and instead introduced sub-typing, mixin,
which Walter said:
https://forum.dlang.org/post/rb4seo$bfm$1@digitalmars.com
""" The trouble was, it was inserted without realizing it was multiple inheritance, meaning its behaviors are ad-hoc and don't make a whole lot of sense when examined carefully. """
Proposal:
On Tuesday, 29 September 2020 at 09:56:47 UTC, Petar Kirov [ZombineDev] wrote:
This is an interesting idea, basically implement the Eiffel compiler (the OO part) as a D library, and perhaps also use openmethods, then we will have a Lisp's multi-methods + Eiffel OO inheritance.
I'm not sure how complex this implementation is going to look like.