Anthony J H Simons, MA PhD

Senior Lecturer in Computer Science

You are here: Simons Home / Research / Projects / Poppy /
Department of Computer Science
Verification and Testing Research Group
The Brunel Object-Oriented Language
The Poppy Object-Oriented Language

The Poppy Object-Oriented Language

Poppy is a compact and expressive object-oriented programming language, exemplifying the theory of classification. The type system for Poppy is based on the second-order theory of F-bounds [1], rather than the first-order theory of subtyping [2]. Classes are treated as parametric polymorphic families of types, possessing at least a given interface. While the formal treatment of polymorphism would normally require the use of type parameters, Poppy deliberately hides this in its surface syntax, using systematic type substitutions [3] on class identifiers to describe the propagation of new types into variables, when these are bound to more specific objects. Class parameters are rebound, especially during inheritance, where the self-type evolves automatically [4]. The type system checks that each method invocation is correctly typed in the calling context, by propagating specific types into general variables. As a result, Poppy naturally supports second-order classes, whose methods are recursively closed over each new class, avoiding the problems associated with covariant argument restriction in type systems based on first-order subtyping [5].

Project History

This is a new project, currently seeking to attract EPSRC funding for an RA and a PhD student. It is based on formal results from the Theory of Classification and experimental work on parametric language design in the Brunel 2.0 programming language. Poppy is the first practical object-oriented programming language to treat classes correctly as second-order polymorphic families of types (c.f. the type classes in Haskell), unifying the notion of class with the usual parametric treatment of generic types.

Poppy also aims to be a practical language, hiding the complexity of polymorphic types and type propagation into parameters from the programmer, where this can be handled in more effective ways. As an example of how elegant the syntax of the Poppy language might look, imagine a Pair class representing an ordered pair of values:

class (Pair self) extends (Object super) {
  class First renames Object;            /* First class */
  class Second renames Object;           /* Second class */
  
  First first;                           /* first projection */
  Second second;                         /* second projection */
  
  Pair copy(First left, Second right) {  /* copy constructor */
    first := left;
    second := right;
    self
  }
}

This illustrates a number of syntactic aspects central to the design of the language (as well as a few other things explained below):

  • The default encapsulation rule granting public read-only access obviates the need for keywords; the most common cases requires no visibility, scope or abstract annotations;
  • Explicit introduction of self and super variables, treated just like other variables - supports explicit method combination on multiple parent classes;
  • Construction allocates a blank object, whose state is copy-initialised under the object's control; supports object streaming with many fewer constructors;
  • Methods only need parentheses where arguments are supplied; supports the fusion of access methods and attributes; both return a result.
Now, imagine a more restricted Entry class, representing an entry in a phone book, which specialises the Pair class, so that the first projection is a String, and the second projection is an Integer:

class (Entry self) extends (Pair pair, TotalOrder order) {
  class First renames String;            /* First rebound */
  class Second renames Integer;          /* Second rebound */
  class Other renames Entry;             /* Other binary class */

  Boolean lessThan (Other other) {
    first.lessThan(other.first)          /* Compare on names */
  }  
  Boolean equal (Other other) {
    first.equal(other.first)             /* Compare on names */
  }
}

This illustrates a number of other features, principally how easy it is to specialise the types of fields and methods, but also the use of multiple classification:

  • Multiple classification of concepts: an Entry is both a kind of Pair and a kind of TotalOrder;
  • Type substitution: the First and Second parameters are rebound to more constrained classes;
  • Adaptation of inherited methods: methods obtained from TotalOrder adapt to the Entry class.
  • Binary methods: arguments can be the same class as self, or a subclass of self's class;
  • Simple method syntax: all methods return a result, the last expression in a sequence.
For further examples of how Poppy might look in practice, browse some of the example classes in the Poppy source code directory. Please note that this is a work in progress and ongoing changes may mean that styles may not yet be consistent.

Related Publications

The main working document about Poppy is the Poppy Language Manifesto. Please note that this is a work in progress, and is still being developed. We put this version out to stimulate some early discussion!

Nothing ese has appeared in print that is directly related to Poppy. Earlier related publications in object-oriented type theory and language design may be found on:

Regent Court, 211 Portobello Street, Sheffield S1 4DP, United Kingdom