Record Polymorphism
SML# supports record polymorphism, which makes SML's field selection operators #<label> and record patterns fully polymorphic, as seen in the following example:
# fun f x = #name x; val f = fn : ['a, 'b#{name:'a}. 'b -> 'a] # f {name = "Joe", age = 21}; val it = "Joe" : string
where ['a, 'b#{name:'a}.'b -> 'a] indicates that f is a polymorphic function operating on any record containing a name field of some type 'a and returns that value of type 'a.
In addition to those simple filed selection, SML# also allow polymorphic functional filed update operation by the syntax
exp # {label1 = exp1, ..., labeln = expn}
that creates a new record from the given record expression exp by changing its labeli value to expi. The folloing is a useful ideom frequently appearing in a program manipulating records.
# fun incX (x as {X,...}) = x # {X = X + 1}; val incX= fn : ['a#{X:int}.'a -> 'a} # incX {X = 1, Y = 2}; val it = {X = 2, Y = 2} : {X:int, Y:int}
Moreover, the SML# compiler always compiles thoese polymorphic record operations into efficient load instructions with an integer offset. The following is an example compilation.
# fun makeGreeting {name= {first = "David", ...},...} = "Hi, Dave" > | makeGreeting {name = {last,...}, ...} = "Dear Mr./Ms." ^ last;
Record Compiled to: val makeGreeting = ['a#{name:'b},'b#{first:string, last:string}. fn {$175, $174, $173, $167} => bind $170 = $167[$175] in bind $171 = $170[$174] in switch $171 of "David" => "Hi, Dave" | _ => bind last = $170[$173] in "Dear Mr./Ms." ^ last end end end ]
makeGreeting function is compiled to a function that takes a record ($167) together with three integer offsets ($173,$174, and $175) for name, first, and last fields, and accesses these feilds directly with the offet values.
Keyword(s):
References:[Features of SML#]