This is a bug:

class A [T] { virtual fun f : 1 -> T; }
instance A[int] { fun f : 1 -> int = "1"; }
instance A[long] { fun f : 1 -> long = "2L"; }
open A[long];
//open A[int];
println$ f ();


prints 2. If I uncomment the A[int] case it prints 1.
Even if I swap the order of the two opens or the two instances.

It should be ambiguous of course. What happens is this:

We have an symbol:

type entry_kind_t = {
  (* the function *)
  base_sym: bid_t;

  (* the type variables of the specialisation *)
  spec_vs: (string * bid_t) list;

  (* types to replace the old type variables expressed in terms of the new
   * ones *)
  sub_ts: t list
}


What this means is: base_sym is just an integer which refers to the symbol
table, which is a hashtable indexed by integers.

The spec_vs and sub_ts work like this: suppose the base_sym is:

        fun f[T1, T2] ....

Then sub_ts are specialisations of T1 and T2 like:

        T1 = int * U
        T2 = U * long

Notice these specialisations can be partial specialisations. The have 
a type variable U in them. That is what the spec_vs is for, it is U.

SO: entry_kind_t is a partial specialisation, nothing more or less!

Now, when we look up a symbol in Felix by name, we have two things
we can find in a given symbol table (scope):

type entry_set_t =
  | FunctionEntry of entry_kind_t list
  | NonFunctionEntry of entry_kind_t


The second one, a NonFunctionEntry is a type or variable or whatever.
The first one is a set of partial specialisations of functions.

Our symbol table then looks like this:

type name_map_t = (string, entry_set_t) Hashtbl.t

Ok, so now, when we open some classes we have to make a composite
symbol table. This means for functions, we may have TWO partial specialisations
of the same function. Which is exactly what we do have in the "bug" case
at the start of this mail.

The problem is .. they're the SAME specialisation!  And the compiler has
a function to merge FunctionEntry's, by joining the lists, BUT it removes
duplicates. This is necessary because you can inherit a function
into two classes, and its the same function. It's not ambiguous, just because
both classes got opened.

So what we have is in effect

base_sym = "f"
spec_vs = [] 
spec_ts = []

because f's signature doesn't contain T (this is the bug I think!
It should be qualified by the type variables anyhow)

So one of these just gets merged away.

This explains why "fopen_input" and "fopen_output" don't cause
an ambiguity when they should. Functions is a polymorphic class
should always have the full set of type variables (even if they're
not all used in the signature).

 --
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today.
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to