At present if you have a function accepting a record with
the set of fields F, you can call it with a record with
the set of fields G, provided F is subset of G, and,
you *explicitly* coerce G to F:

typedef F = (a:int);
typedef G = (a:int, b:int);
fun f(x:F)=>x.a;
var g = (a=1, b=2);
println$ f( g :>> F);

If you leave off the coercion, you will get this:

Client Error binding expression (f g)
CLIENT ERROR
[lookup_name_with_sig] Can't find f of struct  {a:(int);b:(int);}
In /Users/johnskaller/felix/./ft.flx: line 5, cols 9 to 10
4: var g = (a=1, b=2);
5: println$ f( g);
           **
6:


There's an argument to provide "some kind of subtyping" here:
a G "is an F" (it just has extra fields). The coercion we use has
a common generic name in algebra: "the forgetful functor",
which is a structure preserving map that simply "forgets" some
of its domains structure.


If we could do automagical coercions, you could write "generic"
functions and just call them with any record which extended
the parameter type, without having to bother with the coercion.

If there were multiple matches, then we can use the "best match"
rule we currently use, but applied to record specialisations instead
of type variable specialisations: if one coercion forgets fields X
to make a match, and another forgets fields X \cup Y we'll pick the
one that forgets the least fields, namely the one that merely forgets X.

Note that X is a strict subset of X \cup Y: two coercions H and K are
only comparable if, of the set of fields they forget, one is a subset
of the other.

Now, the problem I have implementing this is it appears at first
glance to require a "hack" to the unification algorithm. Unification
solves for type variables. Specialisation is a modification of unification
that specifies some type variables are independent, and some dependent.
Independent types variables are regarded as existential, that is,
they're actually fixed but unknown types, and so we're not allowed
to replace them. For example

        parameter = int * v 
        argument = w * int

unification generally would provide a solution 

        v = int
        w = int

but we do not wish to allow that, we only want to allow specialisation,
we don't want to allow w to be replaced, only v. Roughly in the equation:

        int * v = w * int

we only want to allow variables on the LHS to be replaced, so in this case
there's no solution.

Because of the way the unification algorithm works, it isn't possible to just
ask for "only substitutions of variables on the LHS" because sometimes
variables on the RHS get put on the LHS by a substitution, so we have
to list the dependent variables we want to solve for.

Ok, so, the point is just saying "we want to allow the LHS to unify with the
RHS if the LHS is a record and the RHS is a record with more fields" will
not work. In fact all hell would break loose.

So I'm thinking of this solution: if the LHS is a record, we just replace
it with a new dependent variable. Then, unification will match ANY type.

Then, AFTER we have got the result back from unification, we apply the
subtyping rule as a constraint. So, suppose we have

typedef F = (a:int);
typedef G = (a:int, b:int);
fun f(x:F)=>x.a;
var g = (a=1, b=2);
println$ f( g );

then we match f[v] of (v) instead of f of F.
We get a match with most general unifier (mgu) 

        v -> G

Now we apply the constraint:

        F is subtype of G

which in this case passes: f is a candidate.

It's vital to know that this subtyping doesn't necessarily apply in general.
It *could* apply for records nested in records and tuples provided we're
willing to reconstruct the whole top level record or tuple with a sliced back
component.

More on this later. However the proposal is to hack the overloading
algorithm to change record argument to a variable and retrofit
the record subtyping rule as a constraint.


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




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to