Identifier resolution, the great implementation defined mess.

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 21 23:04:39 PDT 2014


On 9/21/2014 2:17 PM, ketmar via Digitalmars-d wrote:
> On Sun, 21 Sep 2014 13:04:49 -0700
> Walter Bright via Digitalmars-d <digitalmars-d at puremagic.com> wrote:
>
>> I don't know what mental model people have for how lookups work, but
>> the above algorithm is how it actually works.
> i believe that people expect this:
>
>    void foo (int a) {
>      import a;
>      a.bar(); // here we use 'a' module
>      xyzzy(); // it's actually 'a.xyzzy', and 'a as module' is implicit
>      writeln(a); // here we use 'int a' argument

Context dependent lookups? That's an awful lot more complex than the existing rules.

>    }
>
> i.e. symbol resolver will try argument/local name first, and only if it
> failed tries to search in module.

That's how it does work. It's just that parameters are in an enclosing scope.


> or, more complicated sample:
>
>    struct A { int bar; int baz; }
>    void foo (in A a) {
>      import a;
>      a.bar(); // KABOOM, conflicting names
>      xyzzy(); // it's actually 'a.xyzzy', and 'a as module' is implicit
>      writeln(a); // KABOOM (both module and arg are complex types
>      writeln(a.baz); // it's ok until module 'a' doesn't have 'baz'
>    }
>
> i'm not saying that this is how things *must* work, but this is what
> one excepts, i think.

I have no idea how to even write such rules, let alone what kind of error 
messages to generate when the user does it wrong.

I believe it is far better to have simple rules, easy to explain, and have a few 
awkward edge cases than having a terribly complex setup with special cases that 
nobody understands.

For example, probably 3 people on the planet understand C++ overloading rules 
(pages and pages of trivia). The rest just try things at random until it appears 
to work.



More information about the Digitalmars-d mailing list