On Fri, 2007-11-30 at 23:14 +1100, skaller wrote: > test case: > ////////////////////////////////////// > typeclass X[t] { virtual fun f: t -> int; } > instance X[double] { fun f:double -> int = "5555"; } > instance X[int] { fun f:int-> int = "7777"; } > instance X[string] { fun f:string-> int = "9999"; } > > open X[double]; > println (f 1.2); // 5555 > //println (f "jhg"); // FAILS AS IT SHOULD > > proc g[t with X[t]](a:t) { > var x = f 1; // BUG! should FAIL, not produce 7777 > println x; > var y = f a; // should WORK due to function arg, 9999 > println y; > var z = f 1.2; // BUG! should FAIL despite global open > println z; // because the 'with' in g should hide the global > } > > g("Hello"); > /////////////////////////////////// > > both the BUG statements actually work. The // FAILS AS IT SHOULD > correctly fails in similar circumstances.
I have fixed this now -- by reverting to an older piece of code that had this comment on it: (* WRONG!! dunno why, but it is! *) print_endline ("DEPENDENT VARIABLES ARE " ^ catmap "," si (IntSet.fold (fun i l-> i::l) !dvars []) ); print_endline "..."; *) (* let mgu = maybe_specialisation syms.counter syms.dfns eqns in *) (* doesn't work .. fails to solve for some vars which aren't local vs of the fun .. this case: fun g2[w with Eq[w,w]] (x:int,y:int)=> xeq(x,y); doesn't solve for w checking xeq(x,y) .. not sure why it should tho .. w should be fixed already by the instance match .. hmm .. *) let mgu = try Some (unification true syms.counter syms.dfns eqns !dvars) with Not_found -> None in well now, in fact, in fun g2[w with Eq[w,w]] (x:int,y:int)=> xeq(x,y); it is CORRECT that this fails to solve for w. It shouldn't: w is a fixed argument passed to g2 (it cannot be deduced). however this note: var z = f 1.2; // BUG! should FAIL despite global open println z; // because the 'with' in g should hide the global appears to be wrong.. this actually works. It seems the global open is not in fact hidden. This is correct, now I think of it. The reason is: UNLIKE C++ Felix overloads across namespace and scope boundaries. In other words this works: fun f: int -> int; fun g() { fun f: double -> double; f 1; } The f of double doesn't hide the f of int. In the example you'd think f of t would hide f of double, because t is more general, but this is NOT the case: t is just a specific type 't' which happens to be unknown: it isn't a variable, but an unknown constant (just like 'string'). So it cannot hide anything except itself. -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ------------------------------------------------------------------------- SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future. http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4 _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language