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
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language