Linear Types
Dryft uses a linear type system to achieve memory safety without garbage collection. Every value must be used exactly once, eliminating memory leaks and use-after-free errors.Why Linear Types?
Linear types enable:- Memory safety without garbage collection
- Lightweight runtime suitable for embedded systems and performance-critical applications
- Explicit resource management where resource lifecycles are visible in code
- No use-after-free bugs - the compiler prevents them
- No memory leaks - resources must be explicitly consumed or freed
The Linear Type Philosophy
While linear types can seem restrictive in traditional languages, they work naturally with stack-based languages. In Dryft:- Working data lives on the shared stack
- The difference between consuming and non-consuming operations is pronounced
- It’s harder to “forget” to free a resource
- Not using a value automatically returns it in a way
Value Consumption
In Dryft, most operations consume their inputs from the stack:Non-Consuming Operations
Some operations don’t consume values - they copy them:The copy Operation
Usecopy (or ^) to duplicate a value:
Practical Example
Variables and Linear Types
Variables in Dryft interact with the linear type system:Reading Variables
Reading a variable with$ moves the value from the variable:
Using Variables Multiple Times
To use a variable multiple times, reassign it:Linear Types in Practice
Factorial Example
- Each read of
$nconsumes it - We immediately write a new value back with
n! - Variables maintain the linear invariant
Swap Operation
Drop Operation
Explicitly discard a value withdrop (or v):
Resource Management
Linear types shine in resource management:handleis not used after being closedhandlecannot be forgotten - it must be consumed (closed)datais used exactly once
Copy vs Move Semantics
Move (Default)
Most operations move/consume values
+,-,*,/,mod- Comparisons:
=?,>?,<? - Logical ops:
both?,either? - Variable write:
x!
Copy (Explicit)
Use
copy to duplicatecopyor^- Variable read with copy:
$x copy - Non-consuming pattern
Benefits of Linear Types in Stack Languages
Explicit Data Flow
The stack makes value lifetimes visible:Natural Resource Handling
In concatenative style, resources flow through transformations:Prevention of Common Errors
Comparison with Other Languages
Rust
Rust uses affine types (at most once) with borrowing. Dryft uses linear types (exactly once) without borrowing, which is simpler but requires explicit copying.Austral
Dryft was inspired by Austral’s linear types. The stack-based nature makes linear types feel more natural than in traditional languages.Working with Linear Types
Common Patterns
Using a value multiple times:v exactly once.
Type System Integration
Linear types work with Dryft’s static type system:- What types are on the stack
- How many times each value is used (linear property)
Limitations and Trade-offs
However, this explicitness provides:- Complete control over resources
- Guaranteed memory safety
- Zero-cost abstractions
- No runtime overhead
Summary
- Every value must be used exactly once
- Operations consume their inputs by default
- Use
copyto duplicate values for multiple uses - Use
dropto explicitly discard values - Variables follow linear rules: reads consume, writes replace
- Linear types prevent leaks and use-after-free
- Stack-based languages make linear types natural and intuitive