Source Model
Lumen accepts two first-class source formats:
- Markdown files:
.lm.md,.lumen.md - Unfenced source files:
.lm,.lumen
Markdown-Native Files (.lm.md, .lumen.md)
For markdown source, Lumen extracts code from fenced lumen blocks:
# My Program
This is documentation that stays with the code.
```lumen
cell main() -> String
return "Hello, World!"
end
```
More documentation here.
```lumen
cell helper() -> Int
return 42
end
```The compiler:
- Reads the markdown file
- Extracts all
```lumencode blocks - Concatenates them into a single source
- Compiles and executes
Unfenced Source Files (.lm, .lumen)
Unfenced source files are compiled without requiring fenced code blocks:
cell main() -> String
return "Hello from unfenced source"
endUse .lm/.lumen when you want direct source files. Use .lm.md/.lumen.md when you want code and narrative in one file.
The compiler accepts the same directives and interpolation features in both fenced and unfenced source.
Top-Level Directives
Directives control compilation behavior:
@strict true
@deterministic true
@doc_mode falseDirectives must appear at the top of the file, before any declarations.
@strict
Controls strict type checking:
@strict true # Enable strict checking (default)
@strict false # Relax some checksStrict mode:
- Reports unresolved symbols
- Catches type mismatches
- Requires explicit effect declarations
- Validates where constraints
@deterministic
Rejects nondeterministic operations:
@deterministic trueWhen enabled:
uuid()anduuid_v4()are rejectedtimestamp()is rejected- External tool calls require explicit effect declarations
- Future scheduling defaults to
DeferredFifo
@doc_mode
Relaxes checks for documentation:
@doc_mode trueUseful for writing example snippets that reference undefined types.
Code Blocks
Standard Blocks
```lumen
cell main() -> Int
return 42
end
```Ignored Blocks
Code blocks without the lumen language tag are ignored:
```python
# This is not processed
print("hello")
```Module Structure
A single file is a module:
# Math Utilities
```lumen
export cell add(a: Int, b: Int) -> Int
return a + b
end
export cell multiply(a: Int, b: Int) -> Int
return a * b
end
```Imports
Import from other modules:
import math: add, multiply
cell main() -> Int
return add(2, 3)
endImport all exports:
import utils: *Import with alias:
import math: add as plusFile Resolution
When importing import foo: bar, resolution checks:
foo.lmfoo.lumenfoo.lm.mdfoo.lumen.mdfoo/mod.lmfoo/mod.lumenfoo/mod.lm.mdfoo/mod.lumen.mdfoo/main.lmfoo/main.lumenfoo/main.lm.mdfoo/main.lumen.md
Best Practices
Documentation-First Modules
Prefer .lm.md/.lumen.md for user-facing modules so design notes, examples, and implementation stay together:
# User Service
Handles user authentication and profile management.
## Data Model
```lumen
record User
id: String
name: String
email: String where email.contains("@")
end
```
## Authentication
```lumen
cell authenticate(email: String, password: String) -> result[User, String]
# Implementation
end
```Source-Only Modules
Use .lm/.lumen for modules that do not need embedded prose, such as generated code or low-noise internals.
Organization
Keep related code together:
# Error Types
All error types for the user service.
```lumen
enum AuthError
InvalidCredentials
UserNotFound
AccountLocked
end
enum ProfileError
InvalidEmail
UsernameTaken
end
```Next Steps
- Types — Type system overview
- Declarations — Top-level declarations