University of Dublin
Trinity College
Department of Computer Science
Building programming languages
from components
Simon Dobson
Changing contexts for computer science
• systems distributed at Internet scales - security, robustness, ...
• component-based software engineering
Challenges for programming languages
• new constructs, new applications
• changing programmer demographics
Can see languages themselves as component systems
• rapid experimentation
• domain-specific languages made easy
My aim: to tell you about some work we’ve been doing
in this area
Programming languages from components - 2
Language challenges
Need to experiment with languages quickly
• language - programming in the huge, composition operators, how
known features mutate in new circumstances
• trust management - security, authentication, webs of trust
• tools - component repositories, code selection
• the balance between control and expressiveness
A compiler is a big piece of kit
• typically much bigger than the average program written using it
• hard to get source, hard to understand once you’ve got it
• barrier to entry into language design too high for many
Programming languages from components - 3
A language as a component system
Many (most?) language features are orthogonal
• don’t need to know exactly what expressions are available to
describe a sequential composition of them
• substantial independent re-factoring of features
(fun( Int n ) n + 1)(11)
auto Int with [| 1, 2, 3 |]
exp1 ; exp2
The details of the subfeatures aren’t really
important in defining
the feature itself
Features tend to be compositional: they often work by
combining sub-expressions without inspecting them
Programming languages from components - 4
What does this mean?
A language is a composition of features
• typing and behaviour - and syntax too, to an extent
Specify the features independently, and compose
• there will be some dependencies…
• …but a lot more independence
re-use - leverage feature independence
easy experimentation - just a composition exercise
extensibility - present features as syntax, or libraries, or hidden
targeting - exactly the features you want, how you want them
performance - generality brings overheads
complexity - dependencies, novel approach
Programming languages from components - 5
We’ve been developing an experimental
language design system called Vanilla
• build interpreters from language fragments (“pods”)
• re-use existing fragments
• incrementally construct language tools
Standard pods cover a large sub-set of the language
design space
• imperative, functional, “typeful”, object-oriented
• 100% pure Java
The idea is to be able to experiment with (and deploy)
new language variants quickly and easily
Programming languages from components - 6
Vanilla architecture
A framework with core
algorithms running over
a set of components
providing the actual
Type checker
Record attributes
derived from typing
for use at run-time
Programming languages from components - 7
Component phases
Phase walks the AST
Components express
an interest in the
different node types
Having several
overloads the
abstract syntax
Programming languages from components - 8
Try each interested
component until one
succeeds, one fails, or all
decline to commit
Some interesting
generalisations - e.g.
functions taking types,
the “dot” operator, ...
Component/phase interactions
interface TypeChecker {
public Type typeCheck( ASTExpression x,
TypeEnvironment tc, Context c )
throws TypeException;
public Type parseType( ASTType x,
TypeEnvironment tc, Context c )
throws TypeException;
Overall componentbased phase walks
the AST and calls
interested in each
AST node type
Programming languages from components - 9
Recursive calls
access the
complete phase
What’s in a pod
ALL(X <: T) X
Concrete syntax
to abstract syntax
fun(X <: T) …
new UniversalType(…)
Abstract syntax to type
Behaviour may depend on attributes
derived from type-checking
new IClosure(…)
Programming languages from components - 10
Abstract syntax
to behaviour
Some standard pods
• ground types, simple constructed types, control structures, ...
• higher-order closures with currying
Bounded universals
• C++ templates
The basis for functional
programming - no type
inference as yet
Automorphic values
• dynamic typing
-recursive types
• simple self-references
Used for Java/CORBA
object types, too
Objects and classes
• based on Abadi and Cardelli object calculi with covariant self types
Programming languages from components - 11
The Vanilla toolset
• a component architecture for language tools
• implement a single language feature - and only that feature
• try to work uniformly across sub-expressions (e.g. don’t manipulate
them operationally, just evaluate them appropriately)
• batch and interactive interpreters
• parser component generator - generates composable fragments of
recursive-descent parsers from JavaCC-like grammar files
• pod compilers - combine components together into a single class,
eliminating run-time class loading
Samples - an implementation of the O-2 language
Programming languages from components - 12
A language, in Vanilla terms, is just a set of pods
composed together within the framework
• language definition files list the classes
Grammar fragment
Typing and sub-typing
// core pod
Default initial values
Tools instanciate classes into the framework
• …and this is component-based too, of course…
Once loaded, behaves like a “normal” interpreter
Programming languages from components - 13
Pod re-use
Pod usage
• add/change a pod in a language without re-writing the whole thing
• change a component of a pod, without changing the others
Same pods in several languages or variants
• e.g. implement all Pascal and a lot of Java using the standard pods
FOR i := 1 TO 10 DO
j := j + f(i)
for(i = 1; i < 11;
j = j + f(i);
i = i + 1)
Basically we just
eliminate some of the
possibilities syntactically
Programming languages from components - 14
Why do we name the super-class of a class?
• just need to know the (minimal) type of possible super-classes
• “class with a free super-class” (function over classes)
• bind to a real super-class before instanciating
• just change the pod implementing classes - nowhere else
Reify ion with a
particular superclass before
instanciating the
resulting class
Apply the same
functionality to a
family of legal
Must have
Programming languages from components - 15
Don’t over-commit
to the super-class
Client-side CORBA integration
Import IDL definitions directly
off the web - no stub compiler
import idl "";
Random r = bind(Random,
ior "");
Binding builds a DII-based stub
Int i;
Sequence(Int) rs = for(i = 0; i < 10; i = i + 1)
Call the stub like
any other method
IDL maps to Vanilla types through
a component-based mapping
Programming languages from components - 16
As long as we program, we’ll need new language
• composition, security, trust management
• high-level, domain-specific
Vanilla provides an infrastructure for experimentation
• define language features as fragments, and compose
• lots of standard pods to re-use
• experiment quickly across the spectrum of language design
Vanilla is open source, and on the web at
Programming languages from components - 17

A first look at Vanilla