The programming language Mezzo is equipped with a rich type system that controls aliasing and access to mutable memory. We give a comprehensive tutorial overview of the language. Then, we present a modular formalization of Mezzo's core type system, in the form of a concurrent λ-calculus, which we successively extend with references, locks, and adoption and abandon, a novel mechanism that marries Mezzo's static ownership discipline with dynamic ownership tests. We prove that well-typed programs do not go wrong and are data-race free. Our definitions and proofs are machine-checked. XXXX:2 T. Balabonski et al. 1 open woref 2 3 val f (x: frozen int , y: frozen int) : int = 4 get x + get y 5 6 val _ : int = 7 let r = new () in 8 set (r, 3); 9 f (r, r) Fig. 1. Using a write-once ref-erence. The Mezzo type system guarantees that the user must call set before using get, and can call set at most once. and robustness; in return, they offer far greater expressiveness than a simple-minded, purely static discipline could hope to achieve.In this paper, we offer a comprehensive overview of Mezzo, including an informal, user-level presentation of the language and a formal, machine-checked presentation of its meta-theory. This unifies and subsumes the two conference papers cited above. Furthermore, we revisit the theory of adoption and abandon, which was presented informally in the first conference paper, and was absent from the second conference paper. Our new account of adoption and abandon is not only machine-checked, but also simpler and more expressive than that of the conference paper.
A few examplesWe begin with two short illustrative examples. The first one concerns a type of writeonce references and shows how Mezzo guarantees that the client follows the intended usage protocol. The second example is a racy program, which the type system rejects. We show how to fix this ill-typed program by introducing a lock.A usage protocol. A write-once reference is a memory cell that can be assigned at most once and cannot be read before it has been initialized. Fig. 1 shows some client code that manipulates a write-once reference. The code refers to the module woref, whose implementation we show later on ( §2.1).At line 7, we create a write-once reference by calling woref::new. (Thanks to the declaration open woref, one can refer to this function by the unqualified name new.) The local variable r denotes the address of this reference. In the eyes of the typechecker, this gives rise to a permission, written r @ writable. This permission has a double reading: it describes the layout of memory (i.e., "the variable r denotes the address of an uninitialized memory cell") and grants exclusive write access to this memory cell. That is, the type constructor writable denotes a uniquely-owned writable reference, and the permission r @ writable is a unique token that one must possess in order to write r.Permissions are tokens that exist at type-checking time only. Many permissions have the form x @ t, where x is a program variable and t is a ty...