alphaFeedback

WorksComputer Science

Record Types Everywhere

AI contributions
Not recorded for this paper
View details

Abstract

This paper introduces a novel calculus that models first-class environments and function application paradigms using standard record types. By proposing new extensions to general record types, we achieve a design that is remarkably simple and principled. We formalise this design in a core calculus and prove several desirable properties, including type soundness, normalization, and a simulation of the simply typed lambda calculus. Additionally, we extend the design with mutable references. The calculus, its semantics, along with the extension, and all stated properties are fully mechanized in the Lean 4 proof assistant, alongside an interpreter formally verified to be equivalent to the operational semantics.

Introduction

The lambda calculus [7] provides a foundational model for computation and serves as the theoretical basis for modern functional programming languages. A lambda abstraction λx.e\lambda x.e denotes a function binding a variable xx within the body expression ee, with its core evaluation step defined by the β\beta-reduction rule via substitution: (λx.e1) e2⟶e1[e2/x](\lambda x.e_1)\ e_2 \longrightarrow e_1[e_2/x].

However, managing variable bindings remains a classic challenge in language implementation, reasoning, and mechanization. In particular, ensuring variable freshness can be quite tricky. While paper formalisms and pen-and-paper proofs often assume α\alpha-equivalence, concrete implementations typically require more complex machinery such as de Bruijn indices [10] to define capture-avoiding substitution. De Bruijn indices, however, are famously difficult to formalise and implement correctly. Moreover, substitution and de Bruijn indices are often inefficient because reduction requires a traversal of the expression body. Finally, β\beta-reduction fails to capture many common argument-passing paradigms such as named arguments, which allow arguments to be supplied by explicit parameter names.

In this paper, we show how standard record types can be leveraged to model first-class environments [17, 34, 37] and function arguments, establishing an environment-based model that sidesteps traditional binding and inefficiency issues while capturing diverse function application paradigms. Our design is remarkably simple and principled; it uncovers subtle interactions that emerge when combining features and provides a general framework for function application paradigms by exploiting inherent record properties.

We offer the following contributions:

  • A novel design: We propose a design that models first-class environments and function arguments using standard record types (§ 2). Specifically, our design:

    • Is simple and principled, yet naturally expresses diverse features, including first-class environments (§ 2.2), along with named (§ 2.3–§ 2.4), positional (§ 2.5), and optional (§ 2.7) arguments, while supporting a form of partial application (§ 2.6, § 2.7).

    • Generalizes traditional function application paradigms to general records (§ 2.8, § 2.9); and

    • Unifies disparate approaches to handling duplicate labels in record calculi [21, 32] (§ 2.9).

Authors’ Contact Information: Matthew Toohey, University of Toronto, Toronto, Canada, [email protected]; Ara Jamalzadeh, University of Toronto, Toronto, Canada, [email protected]; Ningning Xie, University of Toronto, Toronto, Canada, [email protected].

  • Formalisation: We formalise this design as a core record calculus, λρ+\lambda^{\rho+} (§ 3). We establish key structural properties of its record operators (Lemmas 3.1–3.6), determinacy (Theorem 3.7), type soundness (Theorems 3.8 and 3.9), and normalization (Theorem 3.11). We also prove that it simulates the simply typed lambda calculus (Theorems 3.14 and 3.15).

  • Imperative extension: We extend the calculus with mutable references, under which the precise behaviour of function application becomes important (§ 6). To safely handle type generalization in the presence of side-effects, we adopt the approach of Dolan [ [13] and adapt it to closures and applications.

  • Mechanization: The calculus, including its operational semantics and all stated lemmas and theorems, is fully mechanized in the Lean 4 proof assistant (§ 7). The complete proof artifact is provided in the supplementary materials.

  • Implementation: We implement an interpreter for λρ+\lambda^{\rho+} and formally verify its equivalence with the operational semantics (Theorem 5.1).

Lastly, we explore the broader design space in § 8.

Overview

This section provides an overview of our design. We frequently draw on examples from various programming languages, ensuring the specific language is clear from the context. For further clarity, programs written in our own syntax are enclosed in gray boxes.

The Lambda Calculus with the Substitution Model

Functions, or lambdas, are the core abstraction in the lambda calculus [7]. Its two fundamental rules, governing typing and evaluation respectively, are presented below:

Γ,x:A⊢e:BΓ⊢λx.e:A→BLAM(λx.e1) e2⟶e1[e2/x]BETA\frac{\Gamma, x : A \vdash e : B}{\Gamma\vdash\lambda x.e : A \to B}\quad\mathrm{LAM} \qquad (\lambda x.e_1)\ e_2 \longrightarrow e_1[e_2/x]\quad\mathrm{BETA}

Rule LAM type-checks a function by extending the typing context Γ\Gamma with the argument’s type to type-check the body ee, resulting in the function type A→BA \to B. The evaluation rule BETA substitutes the variable xx with the argument e2e_2 within the body e1e_1.

However, while these two rules are standard in presenting the lambda calculus, they are not without issues. We discuss below some of the challenges of reasoning about and implementing them.

Reasoning about bindings. Reasoning about variable bindings is notoriously difficult, as substitution complicates the metatheory. The substitution function e1[e2/x]e_1[e_2/x] must itself be defined with care: when substituting within a lambda λy.e\lambda y.e, it must respect shadowing when xx and yy coincide and, when reducing open terms, avoid capturing the free variables of e2e_2. Type preservation then rests on a substitution lemma.

To manage bindings, it is common to assume the alpha-convention, where a bound variable can be renamed at any point to ensure its freshness. While this convention is standard in the literature, it does not directly yield a straightforward algorithm for implementation or mechanization.

Another well-known alternative is the use of de Bruijn indices [10], where variables are represented as natural numbers pointing to their corresponding binding sites. However, it is widely acknowledged that implementing and reasoning about shifting, the key operator in de Bruijn indices used to adjust binding numbers during substitution, can be error-prone and non-trivial.

Inefficiency of the substitution model. Another issue is that the substitution model is highly inefficient. Every substitution requires a full traversal of the expression, a process that becomes exceptionally expensive for functions with large bodies. Worse, nested applications trigger this substitution process multiple times, leading to a compounding cost.

Due to this inherent inefficiency, practical languages do not implement beta-reduction using the substitution model. Instead, it is much more common to utilize an environment-based model. Rather than eagerly rewriting the function body every time a variable is bound, the system maintains an environment that maps variable names to their actual values. Consequently, when a function is applied to an argument, the language simply adds that variable-value pairing to the current environment and proceeds to evaluate the function body. By avoiding substitution, an environment-based model also simplifies the metatheory [37 §2.2 and §4.1].

In the literature, a body of work has focused on modelling environments, ranging from calculi with explicit substitutions [1, 3, 8] to the study of first-class environments [17, 34, 37].

Missing function application paradigms. Furthermore, the vanilla lambda calculus does not natively support various function application paradigms common in practical programming languages. For example, many languages support named arguments, which significantly enhance programming convenience by allowing arguments to be provided with explicit names. To illustrate, consider a function written in Python syntax:

def transfer_funds(amount, from_account, to_account): ...

When a programmer wants to call this function using standard positional arguments, they must remember the exact order of the parameters:

transfer_funds(1000, "Alice", "Bob")

Without looking up the function’s definition, this code is difficult to read and highly error-prone. If a developer accidentally swaps "Alice" and "Bob", the code will still execute, but the funds will be transferred from and to the wrong person.

Languages that support named arguments, such as Python, allow programmers to specify the name of the parameter directly alongside the value at the call site:

transfer_funds(amount=1000, from_account="Alice", to_account="Bob")

This way, it becomes immediately clear from the call site which account is transferring to which. Named arguments represent one example of function application paradigms; other important examples include, e.g. optional arguments, which we will discuss further in subsequent sections.

First-Class Environments as Records

In this paper, we develop an environment-based model for the lambda calculus by representing environments as records. This perspective is motivated by the close similarity between a typing context Γ\Gamma, which maps variables to their types, and a record type ρ\rho, which maps labels to types. Consequently, we can update the typing rule LAM\mathsf{LAM} to rule T-LAM\mathsf{T\text{-}LAM} below:

record typeρ::=ε∣ρ,i▹A\text{record type}\quad\rho::= \varepsilon\mid\rho, i \triangleright A
ρ,i▹A⊢e:Bρ⊢λi.e:A→B T-LAM\frac{\rho, i \triangleright A \vdash e : B}{\rho\vdash\lambda i.e : A \to B}\ \mathsf{T\text{-}LAM}

Records are typically expected to be commutative, a property usually captured by a subtyping rule that permutes fields. Under this view, for example, { name:String, age:Int }\{\,\text{name}:\text{String},\ \text{age}:\text{Int}\,\} is equivalent to { age:Int, name:String }\{\,\text{age}:\text{Int},\ \text{name}:\text{String}\,\}. This equivalence naturally reflects the intuition that the typing context is unordered. Therefore, we can formulate a variable typing rule T-VAR\mathsf{T\text{-}VAR} as shown on the right, which, instead of requiring i∈ρi \in\rho, simply requires ii to be the final entry in the context.

ρ,i▹A⊢i:AT-VAR\frac{\rho, i \triangleright A \vdash i : A}{\mathsf{T\text{-}VAR}}

Closures. Similarly, during evaluation, an environment record value oo tracks the values bound to variables. As a result, evaluating lambdas produces closures that capture the variable bindings along with the function:

record value o::=ε∣o,i=vo⊢λi. e⟶⟨o∣λi. e⟩E-lam\text{record value }o ::= \varepsilon\mid o,i=v \qquad o \vdash\lambda i.\,e \longrightarrow\langle o \mid\lambda i.\,e\rangle \quad\text{E-lam}

When the closure is applied to an argument, the function body ee is then evaluated under the environment oo extended with ii bound to that argument.

First-class environments. With first-class environments [17, 34, 37], we can treat environments as first-class objects that can be directly manipulated. For example, we can introduce an operator @ that reifies the environment into a record, with the typing rule \rho\vdash@ : \{\rho\} and the evaluation rule o \vdash@ \longrightarrow\{o\}. We can then apply record operators, such as projection, to the environment. In particular, a variable ii can be considered syntactic sugar for @.ii, which reifies the environment and then projects out the ii field. As another example, a box operator e1▶e2e_1 \blacktriangleright e_2 evaluates e2e_2 within the environment e1e_1, allowing us to directly manipulate the environment in which an expression is evaluated.

As demonstrated by Tan and Oliveira [ [37], first-class environments are useful for modelling first-class modules [5], sandboxed modules, and object capabilities [25, 26]. Our representation of environments as records naturally supports these paradigms, since record objects are themselves first-class.

Named Arguments as Records

Having observed how function applications with named arguments operate in our transfer_funds example, another natural perspective we take is to represent function arguments as records. That is, functions are now typed as {ρ}→A\{\rho\} \to A, allowing them to introduce multiple entries into the context. We introduce record patterns cc with the following typing rule T-lam2:

record pattern c::=ε∣c,ic:ρ2ρ1,ρ2⊢e:Aρ1⊢λ{c}. e:{ρ2}→AT-lam2\begin{aligned} &\text{record pattern }c ::= \varepsilon\mid c,i \\ &c : \rho_2 \qquad\rho_1,\rho_2 \vdash e : A \\ &\rho_1 \vdash\lambda\{c\}.\,e : \{\rho_2\} \to A \end{aligned} \qquad\text{T-lam2}

Here, the record pattern cc defines named function arguments. Rule T-lam2 assigns the type ρ2\rho_2 to the record pattern cc, and updates the typing context to ρ1,ρ2\rho_1,\rho_2, which simply appends ρ2\rho_2 to ρ1\rho_1.

As an example, we can define transfer_funds as follows:

λ{ amount, from_account, to_account }. ...

Function applications can now provide records as named arguments at the call site. For example, the previous example can be written as:

transfer_funds { amount=1000, from_account="Alice", to_account="Bob" }

Thanks to record commutativity, this is equivalent to the following expression, as is desired:

transfer_funds { to_account="Bob", from_account="Alice", amount=1000 }

Shadowing in first-class environments. One may wonder what happens when ρ1\rho_1 and ρ2\rho_2 in rule T-lam2 share the same labels. We support duplicate labels (or scoped labels [21]), which, as we represent environments as records, arise naturally in an environment when shadowing occurs. Duplicate labels are non-commutative with respect to each other, while remaining commutative with different labels. Specifically, projecting a duplicate label from a record returns the rightmost corresponding field (unlike [21], which always returns the leftmost one). For example, {i=2, i=1}.i\{i=2,\ i=1\}.i returns 11. To access the second rightmost one, we can simply write (i=2,i=1\i).i({i=2, i=1}\backslash i).i, which removes \i\backslash i the rightmost ii field from the record, and then accesses the ii field, which effectively retrieves the shadowed ii value 2.

The interpretation that projecting a duplicate label retrieves the rightmost corresponding field directly coincides with the fact that new variables are always appended to the right of an environment (as in rule T-LAM2), thus shadowing prior ones. Therefore, our previous syntactic sugar @.i for variable lookup still holds, as it accesses the latest ii field in the environment. With first-class environments, we can also easily access shadowed fields, e.g. by (@\i).i(@\backslash i).i.

Argument Labels and Parameter Names

We can further separate external argument labels, used at the call site, from internal parameter names, used within the function definition. This distinction allows a function call to read like a sentence, while keeping the function definition itself clear and logical.

The following Swift program, adapted from its official documentation, illustrates this distinction between argument labels and parameter names (the -> String annotation specifies the return type):

func greet(person: String, from hometown: String) -> String {
    "Hello \(person) from \(hometown)."
}

Here, person and hometown bind to the parameters within the function body, while from serves as the argument label used at the call site. We can then call the function as:

greet(person: "Alice", from: "Mars") // "Hello Alice from Mars"

To support the distinction between argument labels and parameter names, we can generalize both record patterns and the typing rule T-LAM2 to rule T-LAM3:

record patternc::=ε∣c,i1⋄i2c:ρ2⊙ρ3ρ1,ρ3⊢e:Aρ1⊢λ{c}.e:{ρ2}→A\begin{aligned} \text{record pattern}\quad c &::= \varepsilon\mid c, i_1 \mathbin{\diamond} i_2 \\ c &: \rho_2 \mathbin{\odot} \rho_3 \qquad\rho_1,\rho_3 \vdash e : A \\ \rho_1 &\vdash\lambda\{c\}.e : \{\rho_2\} \to A \end{aligned}

Here, the record pattern cc captures the distinction (⋄\diamond) between argument labels and parameter names, which are separated (⊙\odot) in T-LAM3 and assigned to record types ρ2\rho_2 and ρ3\rho_3. For example, i1⋄i2i_1 \diamond i_2 can be separated into i1▹Inti_1 \mathbin{\triangleright} \mathrm{Int} and i2▹Inti_2 \mathbin{\triangleright} \mathrm{Int}. The former, ρ2\rho_2, represents the external argument labels and is used as the argument type in the conclusion, while the latter, ρ3\rho_3, represents the internal parameter names and extends the typing context for typing ee. The corresponding rule in § 3.2 additionally performs generalization over the function type; we omit this here for simplicity.

We can now express the example as follows, assuming string interpolation:

λ{ person, from ⋄ hometown }. "Hello \(person) from \(hometown)."

For clarity, we often omit the argument label (e.g. person) when it is identical to the parameter name.

Positional Arguments

The design so far requires every argument to be named. However, positional arguments remain valuable when parameter roles are intuitive enough that explicit labels would only add visual noise. For instance, a function sub(x, y) is naturally expected to compute (x − y) rather than (y − x).

Languages that support named arguments often provide mechanisms for positional arguments as well. In Swift, for example, function arguments are named at the call site by default. When an argument label is unnecessary, Swift developers can use an underscore (_) as the argument label, for example, one can define sub in Swift as the following:

func sub(_ a: Int, _ b: Int) -> Int { a - b }

Here the underscores indicate that the function can be called with positional arguments. This allows the argument labels to be omitted at the call site, e.g. sub(8, 3).

It turns out we can naturally support positional arguments using duplicate labels (§ 2.3). Specifically, by treating the underscore (_) as a normal field label, we can define sub as

sub=λ{_⋄a,_⋄b}.a−b\mathsf{sub} = \lambda\{ \_ \diamond a, \_ \diamond b \}. a - b

The positional application sub {8,3}\{8, 3\} can then be desugared simply into sub {_=8,_=3}\{\_ = 8, \_ = 3\}, where the argument {_=8,_=3}\{\_ = 8, \_ = 3\} is a record with duplicate labels (_). Since duplicate labels do not commute with respect to each other, this effectively models positional arguments.

Mixing named and positional arguments. By interpreting positional arguments as normal records with duplicate labels, our design interprets positional arguments as simply a special case of named arguments. As noted, non-duplicate labels are commutative, while duplicate labels (including the dedicated label for positional arguments) are non-commutative with respect to each other (thus preserving the significance of their order), yet remain commutative with other labels.

As an example, if div is defined with a named dividend and a positional divisor:

div=λ{dividend, _⋄divisor}.dividend/divisor\mathsf{div} = \lambda\{ \mathsf{dividend},\ \_ \diamond\mathsf{divisor} \}. \mathsf{dividend} / \mathsf{divisor}

then both (div {dividend=4,2}\{\mathsf{dividend}=4, 2\}) and (div {2,dividend=4}\{2, \mathsf{dividend}=4\}) are valid and produce the same result, while (div {4,2}\{4, 2\}) is invalid, as named arguments can never be passed positionally.

Our design preserves simplicity by, like Swift, requiring arguments to be declared as named or positional (simply using a dedicated label) in the function definition, making the system easy to reason about. But unlike Swift, which requires the order of arguments at the call site to strictly match the order defined in the function declaration, our system ensures commutativity between distinct labels, allowing for expressive order mixing at the call site. This is particularly useful when combined with partial application, which we discuss below.

Partial Application

So far, we have assumed that all arguments are passed together in a single record. We now generalize this behaviour to support partial application, where only a subset of the arguments are provided at the call site. Partial application is particularly flexible when combined with named arguments and commutativity. For example, consider a function drop that takes a count and a list, and drops count elements from the list. We can fix the list argument and define a specialized dropN function simply by writing drop {list=[’a’,’b’,’c’,’d’]}\{\mathsf{list} = [\text{'a'}, \text{'b'}, \text{'c'}, \text{'d'}]\}.

To achieve partial application, we introduce the following typing rule for function application:

ρ⊢e1:{ρ1}→Aρ⊢e2:{ρ2}ρ1∙ρ2⇝ρ3ρ⊢e1 e2:{ρ3}→A T-APP\frac{\rho\vdash e_1 : \{\rho_1\} \to A \qquad\rho\vdash e_2 : \{\rho_2\} \qquad\rho_1 \bullet\rho_2 \rightsquigarrow\rho_3}{\rho\vdash e_1\ e_2 : \{\rho_3\} \to A}\ \mathrm{T\text{-}APP}

Here, the function e1e_1 expects the arguments specified by ρ1\rho_1, while the argument record e2e_2 provides ρ2\rho_2. The judgement ρ1∙ρ2⇝ρ3\rho_1 \bullet\rho_2 \rightsquigarrow\rho_3 computes the remaining arguments, ρ3\rho_3. In this case, it simply removes ρ2\rho_2 from ρ1\rho_1, though the application process will become more sophisticated later. Consequently, the application yields a function that accepts the remaining arguments, typed as {ρ3}→A\{\rho_3\} \to A.

This rule can be refined in several ways. First, if ρ2\rho_2 is empty, the application does not change the function type at all. To eliminate such “dummy” applications, we can introduce the side condition ρ2≠ε\rho_2 \ne\varepsilon. Second, when ρ3\rho_3 is empty, the resulting type is {}→A\{\} \to A. In this scenario, the application is actually saturated, allowing us to simplify the type to AA; we will revisit this design choice in § 2.7.

We now extend the evaluation rules to support partial application. Specifically, we extend closures to keep track of two record values: one for the environment, and the other for the arguments accumulated so far. This behaviour is captured by the following rules:

o⊢λ{c}.e⟶⟨o;ε∣λ{c}.e⟩E-LAM2o \vdash\lambda\{c\}.e \longrightarrow\langle o;\varepsilon\mid\lambda\{c\}.e\rangle\quad\mathrm{E\text{-}LAM}_{2}
⟨o1;o2∣λ{c}.e⟩{o3}⟶⟨o1;o2,o3∣λ{c}.e⟩E-APP\langle o_1;o_2 \mid\lambda\{c\}.e\rangle\{o_3\} \longrightarrow\langle o_1;o_2,o_3 \mid\lambda\{c\}.e\rangle\quad\mathrm{E\text{-}APP}

When a function abstraction evaluates to a closure, it initializes an empty record ε\varepsilon for the arguments (rule E-LAM2). Subsequent function applications then simply accumulate the provided arguments into this record (rule E-APP). This dual-record setup will serve us well in the next section. Once an application is fully saturated, a beta reduction can occur using all collected arguments (see also § 2.7).

Optional Arguments

In many programming languages, the developer can specify a default value for parameters. For example, we may want to define an exponential function that squares its input by default:

power = λ{ base, exponent := 2 }. base ** exponent

Calling (power { base=3 }) returns 9, while calling (power { base=3, exponent=3 }) returns 27. We refer to arguments with default values as optional arguments, as they can be omitted at the call site, while other parameters are considered required arguments.

Integrating optional arguments into the record pattern is straightforward; we extend cc to include an additional case where a default value vv can be provided.

record patternc::=ε∣c,i1⋄i2∣c,i1⋄i2:=v\text{record pattern}\quad c ::= \varepsilon\mid c, i_1 \diamond i_2 \mid c, i_1 \diamond i_2 := v

We now discuss the typing and evaluation rules for optional arguments.

Typing optional arguments. Since functions with optional arguments such as power can be called with only the required arguments or with optional arguments overwriting the default values, their type signatures must reflect both arities, so that both (power { base=3, exponent=3 }) and (power { base=3 }) type-check and saturate the application.

To this end, we introduce optional types in record types:

record typeρ::=ε∣ρ,i⋆Astrength⋆::=▹∣?\text{record type}\quad\rho::= \varepsilon\mid\rho, i \mathbin{\star} A \qquad \text{strength}\quad\star::= \triangleright\mid?

A record field ii is now associated with a strength ⋆\star, which is either strong (▹\triangleright) or optional (?). When used in function argument types, (▹\triangleright) indicates a required argument and (?) indicates an optional argument. Then, to type-check a lambda definition with optional arguments, the separation operation (⊙\odot) in the typing rule T-LAM3 can be extended to handle the additional case for cc and produce optional types in ρ2\rho_2. For example, the power function can be typed as

References

  1. [1]M. Abadi, L. Cardelli, P.-L. Curien, and J.-J. Levy. 1989. Explicit substitutions. In Proceedings of the 17th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (San Francisco, California, USA) (POPL ’90). Association for Computing Machinery, New York, NY, USA, 31–46. doi:10.1145/96709.96712DOI
  2. [2]Véronique Benzaken, Giuseppe Castagna, and Alain Frisch. 2003. CDuce: an XML-centric general-purpose language. In Proceedings of the Eighth ACM SIGPLAN International Conference on Functional Programming (Uppsala, Sweden) (ICFP ’03). Association for Computing Machinery, New York, NY, USA, 51–63. doi:10.1145/944705.944711DOI
  3. [3]Małgorzata Biernacka and Olivier Danvy. 2007. A concrete framework for environment machines. ACM Trans. Comput. Logic 9, 1 (Dec. 2007), 6–es. doi:10.1145/1297658.1297664DOI
  4. [4]Dariusz Biernacki, Maciej Piróg, Piotr Polesiuk, and Filip Sieczkowski. 2017. Handle with care: relational interpretation of algebraic effects and handlers. Proc. ACM Program. Lang. 2, POPL, Article 8 (Dec. 2017), 30 pages. doi:10.1145/3158096DOI
  5. [5]Luca Cardelli. 1997. Program fragments, linking, and modularization. In Proceedings of the 24th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (Paris, France) (POPL ’97). Association for Computing Machinery, New York, NY, USA, 266–277. doi:10.1145/263699.263735DOI
  6. [6]Arthur Charguéraud. 2011. The Locally Nameless Representation. Journal of Automated Reasoning 49, 3 (May 2011), 363–408. doi:10.1007/s10817-011-9225-2
  7. [7]Alonzo Church. 1941. The Calculi of Lambda-Conversion. Number 6 in Annals of Mathematics Studies. Princeton University Press, Princeton, NJ, USA.
  8. [8]P.-L. Curien. 1991. An abstract framework for environment machines. Theoretical Computer Science 82, 2 (May 1991), 389–402. doi:10.1016/0304-3975(91)90230-YDOI
  9. [9]Leijen Daan. 2014. Koka: Programming with Row Polymorphic Effect Types. Electronic Proceedings in Theoretical Computer Science 153 (06 2014), 100–126. doi:10.4204/eptcs.153.8DOI
  10. [10]Nicolaas Govert de Bruijn. 1972. Lambda calculus notation with nameless dummies, a tool for automatic formulation, with application to the Church-Rosser theorem. Indagationes Mathematicae (Proceedings) 75, 5 (1972), 381–392. doi:10.1016/S1385-7258(72)90034-0
  11. [12]DFINITY. 2026b. Candid Specification: Upgrading and Subtyping. https://github.com/dfinity/candid/blob/d24fb18fadaabb e56b3adb0bb597e49117ca4bfa/spec/Candid.md#upgrading-and-subtyping
  12. [13]Stephan Dolan. 2024. Rethinking the Value Restriction. Higher-order, Typed, Inferred, Strict: ML Family Workshop 2024. Eelco Dolstra and The Nix contributors. 2026. Nix. https://github.com/NixOS/nix
  13. [14]Jana Dunfield and Neel Krishnaswami. 2021. Bidirectional Typing. ACM Comput. Surv. 54, 5, Article 98 (May 2021), 38 pages. doi:10.1145/3450952 , Vol. 1, No. 1, Article . Publication date: October 2026. Matthew Flatt and Eli Barzilay. 2009. Keyword and optional arguments in PLT Scheme. In Proceedings of the Tenth Workshop on Scheme and Functional Programming.
  14. [15]Jacques Garrigue. 2001. Labeled and optional arguments for Objective Caml. In JSSST Workshop on Programming and Programming Languages, Kameoka, Japan.
  15. [16]Benedict R Gaster and Mark P Jones. 1996. A polymorphic type system for extensible records and variants. Technical Report. Technical Report NOTTCS-TR-96-3, Department of Computer Science, University of Nottingham.
  16. [17]D. Gelernter, S. Jagannathan, and T. London. 1987. Environments as first class objects. In Proceedings of the 14th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages (POPL ’87). Association for Computing Machinery, New York, NY, USA, 98–110. doi:10.1145/41625.41634DOI
  17. [18]Mark P. Jones. 1994. Qualified Types: Theory and Practice. Cambridge University Press, Cambridge, UK. doi:10.1017/CBO9780511663086DOI
  18. [19]P. J. Landin. 1964. The Mechanical Evaluation of Expressions. Comput. J. 6, 4 (1964), 308–320. doi:10.1093/comjnl/6.4.308DOI
  19. [20]Mickaël Laurent, Pierre Donat-Bouillud, Filip Křížka, and Jan Vítek. 2026. Reversible Record-Substitution for Set-Theoretic Types. Proc. ACM Program. Lang. 10, OOPSLA2, Article 373 (Oct. 2026), 27 pages. doi:10.1145/3839505
  20. [21]Daan Leijen. 2005. Extensible records with scoped labels. In Proceedings of the 2005 Symposium on Trends in Functional Programming (TFP’05), Tallinn, Estonia. https://www.microsoft.com/en-us/research/publication/extensible-records-with-scoped-labels/
  21. [23]Paul Blain Levy. 2006. Call-by-push-value: Decomposing call-by-value and call-by-name. Higher Order Symbol. Comput. 19, 4 (Dec. 2006), 377–414. doi:10.1007/s10990-006-0480-6DOI
  22. [24]Franek Magiera. 2022. PEP 692 – Using TypedDict for more precise **kwargs typing. Python Enhancement Proposal. https://peps.python.org/pep-0692/
  23. [25]Mark Samuel Miller. 2006. Robust composition: towards a unified approach to access control and concurrency control. Ph. D. Dissertation. Johns Hopkins University, Baltimore, MD, USA. Advisor(s) Shapiro, Jonathan S. AAI3245526.
  24. [26]Mark S. Miller, Chip Morningstar, and Bill Frantz. 2000. Capability-Based Financial Instruments. In Proceedings of the 4th International Conference on Financial Cryptography (FC ’00). Springer-Verlag, Berlin, Heidelberg, 349–378.DOI
  25. [27]J. Garrett Morris and James McKinna. 2019. Abstracting extensible data types: or, rows by any other name. Proc. ACM Program. Lang. 3, POPL, Article 12 (Jan. 2019), 28 pages. doi:10.1145/3290325DOI
  26. [28]Leonardo de Moura and Sebastian Ullrich. 2021. The Lean 4 Theorem Prover and Programming Language. In Automated Deduction – CADE 28: 28th International Conference on Automated Deduction, Virtual Event, July 12–15, 2021, Proceedings. Springer-Verlag, Berlin, Heidelberg, 625–635. doi:10.1007/978-3-030-79876-5_37DOI
  27. [29]Edward Osinski. 2006. A polymorphic type system and compilation scheme for record concatenation. Ph. D. Dissertation. USA. Advisor(s) Goldber, Benjamin F. AAI3221986.
  28. [30]Gordon D. Plotkin and John Power. 2001. Adequacy for Algebraic Effects. In Proceedings of the 4th International Conference on Foundations of Software Science and Computation Structures (FoSSaCS ’01). Springer-Verlag, Berlin, Heidelberg, 1–24.DOI
  29. [31]Gordon D. Plotkin and Matija Pretnar. 2013. Handling Algebraic Effects. Logical Methods in Computer Science 9, 4 (2013). doi:10.2168/LMCS-9(4:23)2013DOI
  30. [32]Didier Rémy. 1994. Type inference for records in natural extension of ML. MIT Press, Cambridge, MA, USA, 67–95.
  31. [33]Lukas Rytz and Martin Odersky. 2010. Named and default arguments for polymorphic object-oriented languages: a discussion on the design implemented in the Scala language. In Proceedings of the 2010 ACM Symposium on Applied Computing (Sierre, Switzerland) (SAC ’10). Association for Computing Machinery, New York, NY, USA, 2090–2095. doi:10.1145/1774088.1774529DOI
  32. [34]Masahiko Sato, Takafumi Sakurai, and Rod Burstall. 2001. Explicit Environments. Fundamenta Informaticae 45, 1–2 (Jan. 2001), 79–115.
  33. [35]Yaozhu Sun and Bruno C. d. S. Oliveira. 2025. Named Arguments as Intersections, Optional Arguments as Unions. In Programming Languages and Systems: 34th European Symposium on Programming, ESOP 2025, Held as Part of the International Joint Conferences on Theory and Practice of Software, ETAPS 2025, Hamilton, ON, Canada, May 3–8, 2025, Proceedings, Part II (Hamilton, ON, Canada). Springer-Verlag, Berlin, Heidelberg, 347–373. doi:10.1007/978-3-031-91121-7_14DOI
  34. [36]W. W. Tait. 1967. Intensional Interpretations of Functionals of Finite Type I. The Journal of Symbolic Logic 32, 2 (1967), 198–212. doi:10.2307/2271658DOI
  35. [37]Jinhao Tan and Bruno C. d. S. Oliveira. 2024. A Case for First-Class Environments. Proc. ACM Program. Lang. 8, OOPSLA2, Article 360 (Oct. 2024), 30 pages. doi:10.1145/3689800DOI
  36. [38]Mitchell Wand. 1987. Complete Type Inference for Simple Objects. In Proceedings of the Symposium on Logic in Computer Science (LICS ’87), Ithaca, New York, USA, June 22-25, 1987. IEEE Computer Society, 37–44.
  37. [40]Andrew K. Wright. 1995. Simple imperative polymorphism. Lisp Symb. Comput. 8, 4 (Dec. 1995), 343–355. doi:10.1007/BF01018828DOI

Paper details

vlnc:W_u3zx8zr3
v1 · latestHistory (1)

published · Fresh — added to the Hub within the last 30 days

added ·

Usage

views · 0

downloads · 0

A view counts once per browser per day, a download each time the PDF is requested.

CC BY 4.0

Original source

  • Computer Science

Not recorded for this paper · View statement →

Looking for related papers…
Contents