Flexible and Reversible Conversion between Extensible Records and Overloading Constraints for ML
Alvise Spanò
TL;DR
The paper addresses interoperability between explicit dictionary passing via records and compiler-driven overloading constraints in ML-like languages. It introduces inject and eject as first-class operators that reversibly transform between constrained functions and record-argument functions, enabling switching between dictionary-passing and constraint-resolution styles with minimal syntactic overhead. A formal type system, together with type inference and correctness sketches, is provided to support nested injections and ejections, restricted forms, and local resolution. The approach aims to improve code reuse across libraries that adopt different dispatch mechanisms, reducing wrapper boilerplate and enabling modular interoperation in a principled way. The work lays groundwork for further formalization, optimization, and potential extension to first-class operator design and overloaded-label extensible records.
Abstract
Most ML-like functional languages provide records and overloading as unrelated features. Records not only represent data structures, but are also used to implement dictionary passing, whereas overloading produces type constraints that are basically dictionaries subject to compiler-driven dispatching. In this paper we explore how records and overloading constraints can be converted one into the other, allowing the programmer to switch between the two at a very reasonable cost in terms of syntactic overhead. To achieve this we introduce two language constructs, namely inject and eject, performing a type-driven syntactic transformation. The former literally injects constraints into the type and produces a function adding an extra record argument. The latter does the opposite, ejecting a record argument from a function and turning fields into type constraints. The conversion is reversible and can be restricted to a subset of symbols, granting additional control to the programmer. Although what we call inject has already been proposed in literature, making it a language operator and coupling it with its reverse counterpart represent a novel design. The goal is to allow the programmer to switch from a dictionary-passing style to compiler-assisted constraint resolution, and vice versa, enabling reuse between libraries that otherwise would not interoperate.
