1.34. Koenig Lookup

Consider the following example:
Start felix section to tut/examples/tut_beg142.flx[1 /1 ]
     1: #line 1825 "./lpsrc/flx_tutorial.pak"
     2: #import <flx.flxh>
     3: 
     4: module A {
     5:   struct X {
     6:     x: int;
     7:   }
     8: }
     9: val e = A::X(5);
    10: print e.x; endl;
End felix section to tut/examples/tut_beg142.flx[1]
There is a subtle point here in this code. (Isn't there always?) Recall that
  e.x
is transformed by desugaring to the function application
  get_x e
If that is so, how is it that the get_x of (A::X) is found, when it is not visible in the top level scope? The answer is that I told a white lie before.

What really happens is that e.x is transformed into a method application. This is exactly the same as a function application, except that overloading uses a special kind of lookup for the method name, called Koenig Lookup, after its inventor, Andrew Koenig.

Koenig lookup works by searching the module in which the type of the expression e is defined: in Felix the type must be generative, which means it must be a declared type such as a named struct or union and not an implicitly defined type like a tuple, pointer, or function type (typedefs do not count here, as in C they just specify an alias, they don't define a type).

In the example, 'get_x' is defined in the module X, because A is defined in the module X, and since e has type 'A', Felix looks in module X for 'get_x'.

Koenig lookup only works for method calls, that is, when you use the syntax e.x.