Eiffel
The object-oriented programming language that pioneered Design by Contract - where software correctness is built into the code itself.
Created by Bertrand Meyer
Eiffel is a programming language that changed how we think about software correctness. Created by Bertrand Meyer in 1986, Eiffel introduced Design by Contract (DbC) - a revolutionary approach where the “contract” between software components is explicitly written into the code and verified at runtime.
History & Origins
In the mid-1980s, Bertrand Meyer was frustrated with the state of commercial software development. After experience with Ada, Simula, and formal specification methods like Z notation, he set out to create a language that would make software reliability a first-class concern.
The Vision
Meyer’s goal was ambitious: create a language where:
- Correctness is provable - Not just hoped for, but demonstrated
- Contracts are explicit - What a routine expects and guarantees is documented in code
- Reuse is safe - Inheritance and polymorphism work correctly by design
- Development is efficient - Despite the rigor, productivity remains high
The Name
Eiffel was named after the Eiffel Tower - a symbol of elegant engineering. Just as Gustave Eiffel’s tower represents structural integrity and aesthetic beauty, the language aims to combine software correctness with clean design.
Design by Contract
Eiffel’s defining contribution to computer science is Design by Contract, now adopted by many modern languages.
The Contract Metaphor
Just as business contracts specify:
- What each party must provide (preconditions)
- What each party will receive (postconditions)
- What both parties agree to maintain (invariants)
Software contracts specify:
deposit (amount: INTEGER)
-- Add amount to balance
require
amount_positive: amount > 0
do
balance := balance + amount
ensure
balance_increased: balance = old balance + amount
end
Contract Elements
- Preconditions (
require) - What must be true before calling a routine - Postconditions (
ensure) - What will be true after the routine completes - Class Invariants (
invariant) - What is always true for any instance of the class
Runtime Checking
Contracts are checked at runtime (in debug mode), catching bugs immediately:
*** PRECONDITION VIOLATION ***
Class: BANK_ACCOUNT
Routine: deposit
Precondition: amount_positive
This “fail fast” approach catches bugs at their source, not downstream.
Why Eiffel Still Matters
1. Influence on Modern Languages
Design by Contract influenced:
- Java - Assertions, though less integrated
- C# - Code Contracts library
- D - Built-in contract syntax
- Rust - Design philosophy of correctness
- Ada 2012 - Added contract-based programming
- Spec# - Microsoft Research extension of C#
2. Multiple Inheritance Done Right
Eiffel solves the “diamond problem” that plagued C++ through:
- Renaming - Inherited features can be renamed to avoid conflicts
- Redefinition - Methods can be overridden with new implementations
- Selection - When features conflict, you explicitly choose which to use
- Export status - Fine-grained control over feature visibility
3. Void Safety
Before Kotlin’s “billion-dollar mistake” solution, Eiffel addressed null references:
feature {NONE} -- Creation
make
do
-- Must initialize all attached attributes
create name.make_empty
end
feature -- Access
name: STRING -- Cannot be Void (null)
optional_data: detachable STRING -- Can be Void, must be checked
4. Command-Query Separation
Eiffel enforces a clean principle: functions return values but don’t change state; procedures change state but don’t return values.
-- Query: Returns count, no side effects
count: INTEGER
do
Result := internal_count
end
-- Command: Modifies state, no return value
increment
do
internal_count := internal_count + 1
end
This makes code more predictable and easier to reason about.
The Eiffel Compilation System
Melting Ice Technology
EiffelStudio uses “Melting Ice” compilation:
- Frozen code - Fully compiled to C, then machine code
- Melted code - Interpreted for rapid development iteration
During development, only changed code is “melted” (interpreted), giving near-instant recompilation. For deployment, everything is “frozen” (compiled) for maximum performance.
Finalization
For production, Eiffel code is:
- Translated to optimized C
- Compiled with your platform’s C compiler
- Linked into a native executable
No runtime environment needed - just like C or C++.
Modern Eiffel Features
Generic Programming
class LIST [G]
feature
extend (item: G)
do
-- Add item of type G to list
end
item: G
-- Current item
end
Agents (Closures)
feature
apply_to_all (action: PROCEDURE [INTEGER])
do
across 1 |..| 10 as i loop
action.call ([i.item])
end
end
example
do
apply_to_all (agent print_number)
end
print_number (n: INTEGER)
do
print (n.out + "%N")
end
end
SCOOP (Simple Concurrent Object-Oriented Programming)
Eiffel’s approach to concurrency:
class WORKER
feature
process (data: separate DATA_SOURCE)
-- Automatically handles synchronization
do
data.fetch
data.transform
end
end
The separate keyword indicates an object may be in another processor/thread, with automatic locking.
EiffelStudio IDE
Eiffel comes with a sophisticated IDE including:
- Graphical class browser - Navigate inheritance hierarchies visually
- Contract viewer - See all contracts for any class
- Automatic documentation - Generate HTML docs from contracts
- Debugging with contracts - Breakpoints on contract violations
- Metrics - Code quality measurements
The Eiffel Community
Resources
- eiffel.org - Official language site
- EiffelStudio - The main IDE (free Community Edition available)
- Eiffel Software - Commercial support and tools
- eiffel.ecma-international.org - ECMA standard documentation
Open Source Implementations
- EiffelStudio GPL Edition - Full IDE, GPL licensed
- Liberty Eiffel - Alternative open-source compiler
- gobo.sourceforge.net - Open-source Eiffel libraries
Getting Started
Eiffel source files use:
.e- Eiffel class files (one class per file).ecf- Eiffel configuration files (project settings)
The convention is lowercase filename matching class name:
bank_account.econtains classBANK_ACCOUNT
A Complete Example
Here’s a small but complete Eiffel class showing contracts:
note
description: "A simple counter with bounds checking"
class
BOUNDED_COUNTER
create
make
feature {NONE} -- Initialization
make (a_max: INTEGER)
-- Initialize with maximum value
require
max_positive: a_max > 0
do
maximum := a_max
value := 0
ensure
maximum_set: maximum = a_max
value_zero: value = 0
end
feature -- Access
value: INTEGER
-- Current counter value
maximum: INTEGER
-- Maximum allowed value
feature -- Basic operations
increment
-- Increase value by one
require
not_at_maximum: value < maximum
do
value := value + 1
ensure
incremented: value = old value + 1
end
reset
-- Reset to zero
do
value := 0
ensure
reset_done: value = 0
end
invariant
value_in_bounds: value >= 0 and value <= maximum
maximum_positive: maximum > 0
end
Every method documents what it requires, what it ensures, and the class maintains its invariant at all times.
Continue to the Hello World tutorial to write your first Eiffel program.
Timeline
Notable Uses & Legacy
Financial Trading Systems
Multiple financial institutions use Eiffel for high-reliability trading platforms where correctness is critical.
Bloomberg Terminal
Parts of the Bloomberg financial software platform were developed using Eiffel.
Amadeus Global Travel Distribution
Travel industry reservation systems using Eiffel for mission-critical booking operations.
Healthcare Systems
Medical software requiring formal correctness guarantees for patient safety.
Embedded Systems
Safety-critical embedded applications where Design by Contract ensures reliable behavior.
Language Influence
Influenced By
Influenced
Running Today
Run examples using the official Docker image:
docker pull eiffel/eiffel:latestExample usage:
docker run --rm -v $(pwd):/app -w /app eiffel/eiffel:latest sh -c 'ec -batch hello.e && ./EIFGENs/hello/W_code/hello'