Richard Cobbe: Research Overview

Environmental Acquisition

We have revisited the idea of environmental
acquisition, as originally proposed by Gil and Lorenz in
a paper at OOPSLA 1996. In a language that supports
acquisition, an object may acquire properties from its
environment. As an example, consider a dialog box that
contains several controls. We don't want to define the error
behavior for each control separately; acquisition allows us
to define it once for the entire dialog and then allow the
controls to inherit this behavior.

Acquisition allows the programmer to model this relationship
directly in the program, rather than relying on inheritance
(which can introduce unwanted subtype relationships) or on
explicit pointer-chasing, which is tedious and error-prone.
Further, it should be possible with a sufficiently advanced
type system to prove statically that, in our
example, the text entry box is always in a context which
provides an error response behavior. As a result, the
programmer does not need to handle incomplete contexts, as
manual pointer-chasing requires.

Object Initialization

Most mainstream object-oriented languages attempt to ensure
that all programs are memory-safe. Despite this guarantee,
however, many OOPLs allow the programmer to refer to an
object's field before that object has been completely
initialized. As a concession to safety, these languages do
ensure that the field's value is well-defined, typically the
value null.

While null is type-safe, it leads to many
problems. First, it is generally not a legal field value
according to the program's invariants. Second, it leads to
severe complications for type-systems that attempt to
restrict where null may apply, as in
Fähndrich and Leino (OOPSLA 2003). Third, in
dynamically-typed languages like MzScheme or Smalltalk, it
restricts the precision of flow analyses: null
will always be in a field's value set.

I am investigating a new object initialization mechanism for
Java-like languages that statically ensures that
every field is initialized before the program accesses it.
A field may still have the value null, but only
when the programmer explicitly requests this behavior, by
specifying null as the field's initial value or
by a field assignment. As a consequence, fields of non-null
types will never contain null, and flow
analyses can be more precise.

Some OO languages have made similar guarantees, but only at
the cost of additional restrictions on code that may be
executed at object creation time. As an example, the most
extreme such restriction is that constructors may not
reference this at all, which prevents several
useful programming paradigms. My proposal avoids this
restriction.

Interface-Oriented Programming

Software engineers and programming instructors have been
teaching people for years that they should program to the
interface of a module, rather than its implementation. This
programming discipline results in better modularity, which
leads to code that is easier to understand and to maintain.

In practice, though, programmers rarely follow this
guideline, as we discovered through a survey of various Java
programs. (The worst offenders were programs, produced by
academic research groups, that evaluate how well student
programs follow similar style guidelines.)

Based on conversations with Java programmers, I believe this
to be a consequence of two phenomena. First, students are
taught to think about interfaces only when they have several
different implementations of that interface from which they
may want to select at run-time. The primary example
is java.util.Set and its implementations, from
the Java API. Students are not taught, however, to use
interfaces when they may have only one implementation at any
given time, but they will have multiple implementations
across the lifetime of the code base.

Second, current OOPLs make it far too easy to depend on the
implementation of a module, even unintentionally. If
programmers are to program only to the interfaces, the
language must provide some way to enforce these abstraction
barriers.

To that end, my advisor and I and several of our colleagues
are working on the design
of Honu, a statically-typed,
class-based object-oriented programming languages that
enforces our ideas of interface-oriented programming. The
primary design decision is that all interactions
between objects—even between superclass and
subclass—must go through a specific interface that the
programmer has defined explicitly.

This work is still in the initial design stages, but early
results are highly promising.