
ifact rt * * Comple A t te n * A te s W i E * s e n l C l I o D C o * D * c u L e m s E u P e Lightweight, Flexible Object-Oriented Generics e n R t v e o d t * y * s E a a l d u e a t Yizhou Zhang∗ Matthew C. Loring∗ Guido Salvaneschiy Barbara Liskovz Andrew C. Myers∗ ∗Cornell University, USA yTU Darmstadt, Germany zMIT, USA [email protected] [email protected] [email protected] [email protected] [email protected] Abstract developers to circumvent limitations in expressivity by using awk- The support for generic programming in modern object-oriented ward, heavyweight design patterns and idioms. programming languages is awkward and lacks desirable expressive The key question is how to expose the operations of type pa- power. We introduce an expressive genericity mechanism that adds rameters in a type-safe, intuitive, and flexible manner within the expressive power and strengthens static checking, while remaining OO paradigm. The following somewhat daunting Java signature for lightweight and simple in common use cases. Like type classes and method Collections::sort illustrates the problem: concepts, the mechanism allows existing types to model type con- <T extends Comparable<? super T>> void sort(List<T> l) straints retroactively. For expressive power, we expose models as The subtyping constraint constrains a type parameter T using the named constructs that can be defined and selected explicitly to wit- Comparable interface, ensuring that type T is comparable to itself ness constraints; in common uses of genericity, however, types im- or to one of its supertypes. However, sort can only be used on a plicitly witness constraints without additional programmer effort. type T if that type argument is explicitly declared to implement the Models are integrated into the object-oriented style, with features Comparable interface. This restriction of nominal subtyping is alle- like model generics, model-dependent types, model enrichment, viated by structural constraints as introduced by CLU [22, 23] and model multimethods, constraint entailment, model inheritance, and applied elsewhere (e.g., [10, 12]), but a more fundamental limitation existential quantification further extending expressive power in an remains: items of type T cannot be sorted unless T has a compareTo object-oriented setting. We introduce the new genericity features operation to define the sort order. That limitation is addressed by and show that common generic programming idioms, including cur- type classes in Haskell [41]. Inspired by Haskell, efforts have been rent generic libraries, can be expressed more precisely and con- made to incorporate type classes into OO languages with language- cisely. The static semantics of the mechanism and a proof of a key level support [33, 37, 39, 43] and the Concept design pattern [30]. decidability property can be found in an associated technical report. However, as we argue, these designs do not fully exploit what type classes and OO languages have to offer when united. Programming Lan- Categories and Subject Descriptors D.3.3 [ This paper introduces a new genericity mechanism, embodied in guages ]: Language Constructs and Features—Polymorphism, Con- a new extension of Java called Genus. The genericity mechanism Language Classifications straints; D.3.2 [ ]: Object-oriented lan- enhances expressive power, code reuse, and static type safety, while Semantics of Programming Languages guages; F.3.2 [ ] remaining lightweight and intuitive for the programmer in common Keywords Genus; generic programming; constraints; models use cases. Genus supports models as named constructs that can be defined and selected explicitly to witness constraints, even for prim- itive type arguments; however, in common uses of genericity, types 1. Introduction implicitly witness constraints without additional programmer effort. Generic programming provides the means to express algorithms and The key novelty of models in Genus is their deep integration into data structures in an abstract, adaptable, and interoperable form. the OO style, with features like model generics, model-dependent Specifically, genericity mechanisms allow polymorphic code to ap- types, model enrichment, model multimethods, constraint entail- ply to different types, improving modularity and reuse. Despite ment, model inheritance, and existential quantification further ex- decades of work on genericity mechanisms, current OO languages tending expressive power in an OO setting. still offer an unsatisfactory tradeoff between expressiveness and us- The paper compares Genus to other language designs; describes ability. These languages do not provide a design that coherently in- its implementation; shows that Genus enables safer, more concise tegrates desirable features—particularly, retroactive extension and code through experiments that use it to reimplement existing generic dynamic dispatch. In practice, existing genericity mechanisms force libraries; and presents performance measurements that show that a naive translation from Genus to Java yields acceptable performance and that with simple optimizations, Genus can offer very good performance. A formal static semantics for a core version of Genus is available in the technical report [44], but omitted here due to lack of space; there we show that termination of default model resolution holds under reasonable syntactic restrictions. 2. The Need for Better Genericity Copyright c ACM, 2015. This is the author’s version of the work. It is posted here by permission of ACM for your personal use. Not for redistribution. The defini- Prior work has explored various approaches to constrained generic- tive version was published in PLDI’15, June 13–17, 2015, Portland, OR, USA. ity: subtyping constraints, structural matching, type classes, and de- http://dx.doi.org/10.1145/2737924.2738008. sign patterns. Each of these approaches has significant weaknesses. 1 class AbstractVertex a single type, whereas in a language with subtyping, each adapted <EdgeType extends type in general represents all of its subtypes. AbstractEdge<EdgeType, ActualVertexType>, No existing approach addresses the first limitation, but an at- ActualVertexType extends tempt is made by JavaGI [43] to fit subtyping polymorphism and dy- AbstractVertex<EdgeType, ActualVertexType>> {...} namic dispatch into constrained genericity. As we will argue (x5.1), class AbstractEdge <ActualEdgeType extends JavaGI’s limited dynamic dispatch makes certain constraints hard to AbstractEdge<ActualEdgeType, VertexType>, express, and interactions between subtyping and constraint handling VertexType extends make type checking subject to nontermination. AbstractVertex<ActualEdgeType, VertexType>> {...} Beyond dynamic dispatch, it is important for OO programming Figure 1: Parameter clutter in generic code. that extensibility applies to models as well. The essence of OO programming is that new behavior can be added later in a modular way; we consider this post-factum enrichment of models to be a class TreeSet<T> implements Set<T> { requirement. TreeSet(Comparator<? super T> comparator) {...} ... } Goals. What is wanted is a genericity mechanism with multiple interface Comparator<T> { int compare(T o1, T o2); } features: retroactive modeling, a lightweight implicit approach for Figure 2: Concept design pattern. the common case, multiparameter type constraints, non-unique con- straint satisfaction with dynamic, extensible models, and model- The trouble with subtyping. Subtyping constraints are used in dependent types. The mechanism should support modular compila- Java [5], C# [14, 21], and other OO languages. In the presence of tion. It should be possible to implement the mechanism efficiently; nominal subtyping, subtyping constraints are too inflexible: they in particular, an efficient implementation should limit the use of can only be satisfied by classes explicitly declared to implement wrapper objects and should be able to specialize generic code to par- the constraint. Structural subtyping and matching mechanisms (e.g., ticular type arguments—especially, to primitive types. Genus meets [10, 12, 23, 26]) do not require an explicit declaration that a con- all of these goals. We have tried not only to address the immediate straint is satisfied, but still require that the relevant operations exist, problems with generics seen in current OO languages, but also to with conformant signatures. Instead, we want retroactive modeling, take further steps, adding features that support the style of program- in which a model (such as a type class instance [41]) can define how ming that we expect will evolve when generics are easier to use than an existing type satisfies a constraint that it was not planned to sat- they are now. isfy ahead of time. Subtyping constraints, especially when F-bounded [7], also tend 3. Type Constraints in Genus to lead to complex code when multiple type parameters are needed. For example, Figure1 shows a simplification of the signatures 3.1 Type Constraints as Predicates of the classes AbstractVertex and AbstractEdge in the FindBugs Instead of constraining types with subtyping, Genus uses explicit project [15]. The vertex and the edge types of a graph have a mutual type constraints similar to type classes. For example, the constraint dependency that is reflected in the signatures in an unpleasantly complex way (See Figure 3 for our approach). constraint Eq[T] { boolean equals(T other); Concept design pattern. Presumably because of these limitations, } the standard Java libraries mostly
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages10 Page
-
File Size-