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

Reply via email to