samrushing/irken-compiler

record patterns ignore the closed/open distinction.

samrushing opened this issue · 1 comments

Because of the way record patterns are compiled, the distinction between a closed and open record is lost. All records patterns are treated as open.

This:

(define thing1
  {a=1 b=2} -> 1
  {a=0 b=0} -> 0
  _         -> -1
  )

Becomes this:

      (function
        thing1
        (m10)
        #f
        (let-splat
          ((m10_b m10.b) (m10_a m10.a))
          (%fatbar
            #f
            (if (eq? m10_b '0) (if (eq? m10_a '0) 0 (%fail #f)) (%fail #f))
            (%fatbar
              #f
              (if (eq? m10_b '2) (if (eq? m10_a '1) 1 (%fail #f)) (%fail #f))
              -1))))

I think the cleanest way to address this starts with the parser, where an open/closed boolean needs to be added to the sexp:record alt. Even then I'm not sure how to propagate that info to the typing phase.

jeske commented

I thought a closed record in the typing phase was a record without rdefault as the final field. Is this not correct?

Eventually, I think (pre) should be applied to supplied data, and (abs) should be supplied to consumed data, such that the above function's type signature would be rproduct (rfield 'a abs int) (rfield 'b abs int), and an "open" version of the above function would be (rproduct (rfield 'a abs int) (rfield 'b abs int) (rdefault abs))