GrammaticalFramework/gf-core

Order of record fields significant when using overload

johnjcamilleri opened this issue · 1 comments

Originally reported by Roman Suzi in gf-dev.

When using an overloaded oper with a record as an argument, the order of that record's fields matters:

abstract Test = {
  cat C;
  fun f1, f2, f3, f4, f5: C;
}
concrete TestCnc of Test = {
  param
    Colour = Black | White ;
    Size = Big | Small ;

  oper
    Rec: Type = {
      c: Colour ;
      s: Size ;
    } ;

    mkRec0: Rec -> Rec = \r -> lin C r ;

    mkRec = overload {
      mkRec: Colour -> Size -> Rec = \c,s -> lin C { c = c; s = s } ;
      mkRec: Rec -> Rec = mkRec0 ;
    } ;

  lincat
    C = Rec ;

  lin
    f1 = mkRec White Small ; -- ok

    f2 = mkRec0 { s = Small ; c = White } ; -- ok
    f3 = mkRec0 { c = White ; s = Small } ; -- ok

    f4 = mkRec { s = Small ; c = White } ; -- ok
    f5 = mkRec { c = White ; s = Small } ; -- fails
}

Error for f5:

 TestCnc.gf:28:
   Happened in linearization of f5
    no overload instance of TestCnc.mkRec
    with value type {s : Size; c : Colour}
    for argument list
      {c : Colour; s : Size}
    among alternatives
      Colour Size
      {s : Size; c : Colour}

The enforced order does not seem to be alphabetical (as previously suspected).

There was an easy fix on line 404, to sort the fields uniformly with sortRec.

For historical reasons, sorting places the 's' field first, other fields alphabetically.

Issue #66 is trickier, since it has to do with the order of record extension and overload resolution in the type checker. I will look at it next. I wrote this code basically in 2006, with a few fixes at later dates.