Timber can be seen as an object-oriented programming language with
many familiar features, but also some less familiar. This page summarizes
both similarities and differences.
-
The Timber compilation unit is a module. Within such a module one
defines e.g. types, functions and classes. So there are many other
entities in Timber than classes and objects.
- The correspondence to a Java interface is a Timber
struct type. Here is an interface suitable for a simple counter object:
struct Counter where
incr :: Action
reset :: Action
read :: Request Int
A class that implements this interface provides two actions
(asynchronous methods, that do not return results): incr
to increment the local integer state by one, and reset to
reset the state to zero. To query the state, we use the request
(synchronous, value-returning method) read, which simply returns
the value of the state.
-
A Timber class consists of
- Declaration and initialization of local state variables;
- Declarations of methods, i.e. actions and requests, that
access and update the state.
- Possibly local, auxiliary, definitions.
- Specification of a result, which typically is one or more
interfaces that the class implements.
Here is a counter class:
counter initVal = class
val := initVal
incr = action
val := val + 1
reset = action
val := 0
read = request
result val
result Counter {..}
The class itself starts with the keyword class. We see
the initialization of the state variable val to initVal,
the three method declaration and finally the result specification;
here Counter {..} means: assemble a value of type Counter
from definitions in scope.
Note that there is no constructor method within the class. Within
the methods of another class we may write
c1 = new counter 0
c2 = new counter 10
to create two counter objects, with initial value 0 and 10, respectively.
- Timber has parametric polymorphism, so the kind of generics
introduced in Java 1.5 is naturally supported.
- Timber provides powerful ways to define new
value-oriented data types and functions on these, without attempts to
force this into an (often ill-suited) object paradigm. A consequence is
that Timber classes have no static variables or methods; such entities
are naturally defined as values and functions outside classes.
-
All types in Timber are first-class, which makes it possible to use classes
and methods as parameters to functions, as function values, as elements in
data structures etc leading to new programming patterns. counter above
is a simple example of this: it has type
counter :: Int -> Class Counter
i.e., it is a function that when applied to a integer (the start value) returns a
class, from which we later can create objects.
- Timber has subtyping between struct types and inclusion polymorphism
but does not support inheritance. Since classes and methods are first-class types
in Timber it is often possible to find other ways to express most useful occurrences of
inheritance.
-
Methods always execute with exclusive access to the state of objects; thus
they can execute concurrently, leading to a very simple concurrency model for
Timber.