namgk / ambienttalk

Automatically exported from code.google.com/p/ambienttalk
0 stars 0 forks source link

Nameclashes during import for modules with a diamond import structure. #3

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Nameclashes occur in when importing 'modules' in the classic diamond situation:
  O { def a() }
 / \ 
A B
 \ /
  C -> nameclash of a() 

concrete code example:

import /.at.lang.traits;
def A := object: { import /.at.lang.traits };
import A; //Conflicting names during import: 
               //requiring:,trait:taggedAs:,trait:requiring:taggedAs:,
               //trait:,trait:requiring:,use:,traitFrom:,TraitsTest,traitFrom:taggedAs:,
               //traitFrom:requiring:taggedAs:

Original issue reported on code.google.com by tvcut...@gmail.com on 14 May 2008 at 8:01

GoogleCodeExporter commented 8 years ago
I consulted the original Traits paper and they indeed mention:

"A conflict arises if and only if we combine two traits providing identically 
named meth- 
ods that do not originate from the same trait. In particular, this means that 
if the same 
method (i.e., from the same trait) is obtained more than once via different 
paths, there 
is no conflict. This rule is semantically sound because traits cannot specify 
state (cf. 
section 4.1)."

So in principle, this means we should modify the behaviour of "import" such 
that it can safely ignore a conflict 
if it can detect that the methods in conflict refer to the same implementation.

Traits can indeed not cope with conflicts arising from importing the same 
implementation multiple times.

Original comment by tvcut...@gmail.com on 14 May 2008 at 8:02

GoogleCodeExporter commented 8 years ago

Original comment by tvcut...@gmail.com on 14 May 2008 at 8:08

GoogleCodeExporter commented 8 years ago
Fixed the issue in interpreter/trunk r1287.

Import now checks whether two delegate methods are equal when a conflict is 
raised. Two delegate methods 
d1(alias1,origname1,referent1) and d2(alias2,origname2,referent2) are equal iff
 either alias1 == alias2 && referent1 == referent2
 or d2 == referent1.&origname1
 or d1 == referent2.&origname2

Note that this allows for some cool behavior, such as merging a previously 
aliased slot back into a single slot, 
as can be witnessed by the 'd' slot in the following unit test (added to 
at/unit/bugfixes.at)

    def testDiamondImport() {
        def A := object: {
            def a() { "A" };
            def d() { "D" };
        };
        def B := object: {
            import A;
            def b() { "B" };
        };
        def C := object: {
            import A;
            def c() { "C" };
        };
        def D := object: {
            import B alias d := e;
            import C alias d := e;
        };
        self.assertEquals("A", D.a());
        self.assertEquals("B", D.b());
        self.assertEquals("C", D.c());
        self.assertEquals("D", D.e());
        self.assertFalse((reflect: D).respondsTo(`d));
    };

Original comment by tvcut...@gmail.com on 17 Sep 2008 at 2:48