Deploy Timber to Europe β Johan Nordlander πΈπͺ (Chalmers 2002), the Reactive Object Language for Real-Time Embedded Systems, on EU Infrastructure in 2026
Most programming languages ask you to choose: either you write type-safe functional code with Haskell-style inference, or you write concurrent object-oriented code with classes and message passing. Timber makes both the same thing. A Timber program is a collection of reactive objects β objects that hold state, respond to external messages, and execute concurrently β described with Hindley-Milner type inference and purely functional value semantics at the core.
Timber was created by Johan Nordlander πΈπͺ at Chalmers University of Technology in Gothenburg, Sweden, with the core language design published around 2002β2003. The goal was direct: build a strongly-typed, garbage-collection-free language for real-time embedded systems where timing guarantees matter and GC pauses are unacceptable. Timber compiles to C and then to native machine code, with no runtime managed memory β making it suitable for microcontrollers, real-time controllers, and embedded applications running under strict latency requirements.
The language remained a research artefact with a small community, but its design solved a real problem: how to apply the insights of functional programming β immutable values, type inference, explicit effects β to the domain of reactive concurrent systems without sacrificing the predictability that embedded engineers require.
Johan Nordlander and the Chalmers Reactive Systems Cluster
Johan Nordlander πΈπͺ did his doctoral work at Chalmers University of Technology, Gothenburg, in the 1990sβ2000s. Chalmers had become one of Europe's leading centres for programming language research β the same institution that produced LML (Augustsson and Johnsson, 1984), the G-Machine that became GHC's compilation model, and Agda (Ulf Norell, 2007), the dependently-typed proof assistant.
Nordlander's earlier work produced O'Haskell β an experimental extension of Haskell with object-oriented features, exploring whether the Haskell type system could express mutable reactive objects without losing soundness. O'Haskell was a research prototype. Timber was the production language that followed from those experiments: cleaner design, C backend, explicit focus on embedded real-time systems.
Chalmers Programming Languages Cluster (Gothenburg πΈπͺ):
LML (1984) β Augustsson + Johnsson
G-Machine β basis for GHC native code generation
β
Haskell (1990) β international committee (UK/Sweden/US)
β Chalmers contribution: GHC backends, type class extensions
Gofer (1993) β Mark Jones π΄σ §σ ’σ ³σ £σ ΄σ · (Oxford/Chalmers)
First Haskell type class implementation for education
β
O'Haskell (1998) β Nordlander πΈπͺ (Chalmers)
Haskell + reactive objects + message passing
β
Timber (2002) β Nordlander πΈπͺ (Chalmers)
Reactive OO + Hindley-Milner + real-time + C backend
β
Agda (2007) β Norell πΈπͺ (Chalmers)
Dependently typed proofs and programs
The Chalmers tradition: take a theoretical idea seriously, build a language around it, and let it influence the mainstream years or decades later. LML's G-Machine became GHC. Agda influenced Lean and Idris. Timber's reactive object model anticipated patterns that later appeared in Erlang/OTP (the OTP supervisor model) and in reactive programming frameworks.
Reactive Objects: The Core Design
In Timber, the fundamental unit is not a function or a class β it is a reactive object. A reactive object:
- Has private mutable state (a collection of instance variables)
- Exposes a set of methods (named handlers for incoming requests)
- Executes concurrently with other objects
- Responds to messages asynchronously β callers do not block unless they explicitly request a synchronous result
- Has no garbage collector: memory for object instances is managed via explicit object lifetimes
This model addresses the standard problem with GC in real-time systems. A garbage collector creates unpredictable pauses: code that runs in 1ms normally might stall for 50ms when the GC decides to collect. For an embedded controller managing a motor, a 50ms stall can be catastrophic. Timber avoids this by giving objects explicit lifetimes and using stack allocation for values β the programmer controls when objects are created and destroyed.
-- A Timber reactive object: a simple counter
counter :: Int -> Class Action
counter init = class
val := init
increment = action
val := val + 1
decrement = action
val := val - 1
get = request
result val
The key abstractions:
class: defines a reactive object type β a template for creating objects with shared behaviouraction: a one-way asynchronous message handler β fire and forget, no return valuerequest: a two-way synchronous message handler β caller blocks untilresultis returned:=: mutable state update, confined within method bodies- Type inference: Timber uses Hindley-Milner throughout; types are inferred, not declared
The discipline is strict: mutable state can only be modified inside action or request bodies. Values β integers, lists, algebraic data types β are immutable. This separation makes reasoning about concurrent behaviour tractable: only objects have mutable state, and only one method executes at a time per object (the Timber execution model serialises access to an object's state).
Type System: Hindley-Milner Meets Concurrency
Timber's type system is a direct extension of Haskell's type inference. Polymorphism, type classes, and algebraic data types are available with the same inference rules. The extension is a set of effect types that track whether a computation performs I/O, modifies state, or communicates across object boundaries.
-- Timber type signatures inferred from context
-- (shown here for clarity; usually omitted)
increment :: Action -- sends an async message, no return
get :: Request Int -- sends a sync message, returns Int
fib :: Int -> Int -- pure function, no effects
Effect types ensure at compile time that:
- Pure functions (
Int -> Int) never modify state or send messages Actionhandlers never return values to callersRequesthandlers always produce a result viaresult- Communication patterns are type-checked, not just convention
This approach to effect typing predates Effect Systems that became fashionable in Rust (async/await, Send/Sync) and in Koka (algebraic effects, see post #127 in this series... though Koka came after Timber). The Timber team was exploring typed effects in the context of concurrency at roughly the same time as similar ideas emerged in Haskell and ML research.
Real-Time Guarantees and the Embedded Target
Timber was designed with a specific deployment target: microcontrollers and embedded boards running bare-metal or RTOS environments. The language guarantees:
- No GC pauses: all allocation is either stack-based (values) or explicit object creation/deletion
- Bounded stack usage: Timber's type system rejects programs that create unbounded recursion without tail-call optimisation
- Predictable concurrency: the object execution model provides a well-defined scheduling interface β an embedded OS can implement Timber's concurrency primitives on top of its own scheduler
The C backend is central to this portability. Timber compiles to portable C, which can then be compiled by any embedded toolchain (GCC, Clang, IAR, ARMCC) for any target architecture. A Timber program targeting ARM Cortex-M can use the same source as one targeting x86-64 Linux β the C layer handles ABI differences.
Timber compilation pipeline:
.tim source
β Timber frontend (type check, type inference)
Typed IR
β Timber backend (reactive object lowering)
Portable C
β gcc / clang / arm-none-eabi-gcc
Native binary (x86-64 / ARM / MIPS / RISC-V)
This pipeline was prescient. Today, Rust achieves a similar goal β systems-level safety without GC, on embedded targets β but using ownership and borrowing rather than reactive objects and effect types. The design space Timber explored (safe concurrency, no GC, predictable timing) became the defining requirements of systems languages in the 2010s.
EU Context: Swedish Embedded Systems Research
Timber was produced at Chalmers University of Technology πΈπͺ, supported by Swedish national research funding (STINT β the Swedish Foundation for International Cooperation in Research and Higher Education) and EU research grants under the then-active Information Society Technologies programme.
Sweden has an outsized presence in embedded and real-time systems engineering:
- Ericsson πΈπͺ (Kista/Stockholm) β creator of Erlang, for telecom embedded systems (see post #128 in this series)
- Volvo Cars πΈπͺ β embedded real-time software for safety-critical automotive systems
- SAAB Aerospace πΈπͺ β avionics real-time software (DO-178 certified)
- ABB πΈπͺπ¨π β industrial automation, PLCs, real-time controllers
Chalmers sits in this ecosystem. Timber's design reflects the engineering constraints of the Swedish industrial R&D environment: predictable timing, safety-critical reliability, formal reasoning about system behaviour. The same constraints drove TTCN-3 (ETSI, post #125), which standardised protocol conformance testing for exactly the kind of systems where Timber programs might run.
The EU regulatory environment reinforces this: NIS2 requires cybersecurity risk management for operators of essential services, including embedded infrastructure. IEC 61508 (functional safety for embedded systems, a descendant of CORAL 66, post #123) and IEC 62443 (industrial cybersecurity) both require traceability between software requirements and implementations. A language with strong static typing and effect tracking β like Timber β provides more formal evidence of correct behaviour than a dynamically typed scripting language.
Deploying Timber Applications on sota.io
Timber compiles to C and then to a native binary. Deploying a Timber application to sota.io follows the standard path for compiled languages: build the binary, package it in a container, deploy.
Prerequisites:
# Install Timber compiler (from source, Chalmers distribution)
git clone https://github.com/nordlander/timberΡ
cd timberc
make
export PATH=$PATH:$(pwd)/bin
# Verify
timberc --version
Build and containerise:
FROM debian:bookworm-slim AS builder
RUN apt-get update && apt-get install -y gcc make git libgc-dev
# Build Timber compiler from source
RUN git clone https://github.com/nordlander/timberc /timberc \
&& cd /timberc && make
# Copy source
WORKDIR /app
COPY . .
# Compile Timber β C β native binary
RUN /timberc/bin/timberc -o myservice Main.t
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/myservice .
EXPOSE 8080
CMD ["./myservice"]
Deploy to sota.io:
# Login
sota login
# Deploy directly from current directory
sota deploy --name timber-service --port 8080
# Or with environment variables
sota deploy \
--name timber-service \
--port 8080 \
--env DATABASE_URL=$DATABASE_URL
sota.io provisions the container in an EU data centre, handles TLS termination, and provides a managed PostgreSQL instance for persistence β all GDPR-compliant by default, no additional configuration required.
Timber and Modern Reactive Systems
The patterns Timber introduced have parallels in contemporary systems:
| Timber Concept | Modern Equivalent |
|---|---|
| Reactive objects | Erlang/OTP GenServer, Akka actors |
action (async message) | Elixir cast, Rust tokio::spawn |
request (sync message) | Elixir call, gRPC unary |
| Effect types | Rust async/Send/Sync, Koka effects |
| No-GC objects | Rust ownership, C++ RAII |
| C backend | Rust compiles to LLVM IR β native |
Timber did not achieve mainstream adoption, but it explored the design space that Rust and Erlang/OTP would later occupy from different directions. Rust approached from the systems side (ownership, borrowing, no GC). Erlang approached from the telecom reliability side (actor model, let-it-crash). Timber tried to reach both simultaneously from the typed functional programming side β an ambitious synthesis that was ahead of available tooling and community.
FAQ
Can Timber be used for production systems today?
Timber remains a research language with limited maintenance. For production real-time systems, Rust (RTOS support via Embassy, no_std) or Ada/SPARK (post #18 in this series) are the mature choices. Timber is valuable for studying reactive object design and for embedded education.
Is Timber related to the TIMBER database?
No. TIMBER (Tree-Structured Data Management in Relational Systems) is a database research project from the University of Michigan. The Chalmers programming language Timber and the Michigan database project are unrelated beyond sharing a name.
What is the difference between Timber and Erlang?
Both use a concurrent object/process model with message passing. Key differences: Timber uses Hindley-Milner type inference (Erlang is dynamically typed); Timber targets embedded no-GC environments (Erlang uses GC and targets fault-tolerant servers); Timber uses synchronous request for blocking calls (Erlang uses explicit receive loops). They solve different problems with similar concurrency intuitions.
Does sota.io support real-time workloads?
sota.io provides standard Linux containers with shared CPU scheduling β not a hard real-time environment. For Timber applications that require real-time guarantees, you would run them on dedicated embedded hardware. For Timber services that require EU hosting, network isolation, GDPR compliance, and PostgreSQL persistence, sota.io is the deployment target.
Why deploy to Europe specifically?
EU data residency requirements under GDPR, NIS2, and sector-specific regulations (banking, healthcare, critical infrastructure) require that data stays in EU jurisdiction. sota.io runs exclusively on EU infrastructure, providing the jurisdictional guarantees that US-based PaaS providers cannot match without explicit EU region configuration β and the associated lock-in and complexity.
sota.io is an EU-native PaaS. Deploy any language β including obscure research languages from Chalmers β to European servers with managed PostgreSQL, zero DevOps, and GDPR compliance by default.
Timber was created by Johan Nordlander πΈπͺ at Chalmers University of Technology, Gothenburg, Sweden, 2002. Part of the Chalmers programming language research tradition that also produced LML, Agda, and contributions to GHC.