Shared Immutable State (Shared<T>)
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
In the Sploosh programming language, Shared<T> is a reference-counted primitive used to enable the sharing of immutable data across different parts of a program. Sploosh typically enforces strict isolation through an actor-based concurrency model where mutable state is encapsulated within Actors and shared only via message passing. Shared<T> serves as the primary opt-in mechanism for shared data that does not require the overhead of a message-passing channel, provided that the data remains immutable.
Sources: VISION.md:89-90, README.md:14-18, VISION.md:46-47
Architecture and Concurrency Model
Sploosh follows a "no shared mutable state" philosophy, drawing inspiration from Elixir-style actor concurrency and Rust-style memory safety. While actors manage their own private mutable state, Shared<T> provides a way to distribute large or frequently accessed read-only datasets without deep-copying them during message passing between actors.
Concurrency Context
| Concurrency Primitive | State Type | Access Mechanism |
|---|---|---|
| Actor | Private / Mutable | Message passing (Mailbox) |
Handle<T> | Reference | send / request-reply |
Shared<T> | Shared / Immutable | Direct reference (RC) |
Sources: VISION.md:58-60, VISION.md:86-90, README.md:14-18
Structural Concurrency Flow
The following diagram illustrates how Shared<T> fits into the structural concurrency of a Sploosh application, contrasting it with the private state of an Actor.
This diagram shows that while Actor A and Actor B maintain isolated private states, they can both hold a reference to the same Shared<T> instance for read-only access.
Sources: VISION.md:58-60, VISION.md:89-90
Implementation and Language Integration
The Shared<T> primitive is integrated into the Sploosh type system and is subject to the language's safety constraints. As of the current compiler bootstrap, the lexer and parser identify the necessary keywords and structures to support high-level types, including generic paths and reference types that would underpin Shared<T>.
Type System Characteristics
- Immutability: Data wrapped in
Shared<T>cannot be modified. This prevents data races without requiring locks. - Reference Counting: It is described as a "refcounted primitive," suggesting that the underlying memory is reclaimed only when the last reference is dropped.
- Safety: It avoids the need for complex lifetime management like Rust's
Arc<T>orRc<T>by enforcing immutability at the language level.
Sources: VISION.md:89-90, crates/sploosh-parser/src/lib.rs:448-460, VISION.md:113-115
Parser and Lexer Support
The compiler bootstrap crates (sploosh-lexer and sploosh-parser) provide the infrastructure for handling generic types and paths, which are required to declare a Shared<T>.
// Examples of generic path parsing logic in sploosh-parser
fn ty(&mut self) -> Option<Type> {
// ... logic for references and paths ...
let path = self.path()?;
let args = self.type_args();
if path.segments.len() == 1 && args.is_empty() && is_primitive_type(&path.segments[0]) {
Some(Type::Primitive(path.segments[0].clone()))
} else {
Some(Type::Path { path, args })
}
}
Sources: crates/sploosh-parser/src/lib.rs:448-475, crates/sploosh-lexer/src/lib.rs:135-171
Constraints and Security
Because Shared<T> bypasses the actor mailbox for data access, it is strictly limited to immutable data. This is a core security and safety feature to prevent the introduction of undefined behavior or silent data loss.
Safety Table
| Feature | Requirement | Reason |
|---|---|---|
| Mutability | Forbidden | Prevent data races in concurrent environments. |
| On-chain usage | Restricted | onchain mod rejects non-deterministic surfaces. |
| Cloning | Allowed | Reference counted; safe to pass between actors. |
Sources: SECURITY.md:14-18, VISION.md:82-84, VISION.md:89-90
Conclusion
Shared<T> is a vital component of the Sploosh design philosophy, providing a safe and efficient escape hatch from the strict isolation of the actor model. By allowing immutable refcounted data to be shared directly, Sploosh maintains its performance goals and "prompt-loadable" simplicity while ensuring that the core safety guarantees—no shared mutable state and no data races—remain intact.
Sources: VISION.md:58-60, VISION.md:89-90, README.md:65-71