4 research outputs found
Generic Go to Go: Dictionary-Passing, Monomorphisation, and Hybrid
Go is a popular statically-typed industrial programming language. To aid the
type safe reuse of code, the recent Go release (Go 1.18) published on 15th
March 2022 includes bounded parametric polymorphism via generic types. Go 1.18
implements generic types using combination of monomorphisation and call-graph
based dictionary-passing called hybrid. This hybrid approach can be viewed as
an optimised form of monomorphisation that statically generates specialised
methods and types based on possible instantiations. A monolithic dictionary
supplements information lost during monomorphisation, and it is structured
according to the program's call graph. Unfortunately, the hybrid approach still
suffers from code bloat, poor compilation speed, and limited code coverage.
In this paper we propose and formalise a new non-specialising call-site based
dictionary-passing translation. Our call-site based translation creates
individual dictionaries for each type parameter, with dictionary construction
occurring in place of instantiation, overcoming the limitations of hybrid. We
prove it correct using a novel and general bisimulation up to technique. To
better understand how different generics translations approaches work in
practice, we benchmark five translators, Go 1.18, two existing monomorphisation
translators, our dictionary-passing translator, and erasure translator. Our
findings reveal several suggestions for improvements for Go 1.18 --
specifically how to overcome the expressiveness limitations of generic Go, and
improve compile time and compiled code size performance of Go 1.18.Comment: Full version of paper submitted to OOPSLA '2
Coherence of Type Class Resolution.
Elaboration-based type class resolution, as found in languages like Haskell, Mercury and PureScript, is generally nondeterministic: there can be multiple ways to satisfy a wanted constraint in terms of global instances and locally given constraints. Coherence is the key property that keeps this sane; it guarantees that, despite the nondeterminism, programs still behave predictably. Even though elaboration-based resolution is generally assumed coherent, as far as we know, there is no formal proof of this property in the presence of sources of nondeterminism, like superclasses and flexible contexts.
This paper provides a formal proof to remedy the situation. The proof is non-trivial because the semantics elaborates resolution into a target language where different elaborations can be distinguished by contexts that do not have a source language counterpart. Inspired by the notion of full abstraction, we present a two-step strategy that first elaborates nondeterministically into an intermediate language that preserves contextual equivalence, and then deterministically elaborates from there into the target language. We use an approach based on logical relations to establish contextual equivalence and thus coherence for the first step of elaboration, while the second step's determinism straightforwardly preserves this coherence property.status: Published onlin