|
This project is in early development and not intended for production use. |
Firefly is a novel F# compiler that brings the expressiveness and safety of functional programming directly to native code without runtime dependencies or garbage collection. Built as an orchestrating .NET CLI tool (similar to Fable), Firefly leverages F# Compiler Services for parsing and type checking, custom transformations to generate MLIR, and LLVM for native code generation. The compilation pipeline progressively lowers F# through MLIR dialects, producing efficient native executables with deterministic memory management and compile-time resolution of operations.
Firefly transforms F# from a managed runtime language into a true systems programming language with deterministic memory guarantees. By orchestrating compilation through MLIR, Firefly provides flexible memory management strategies - from zero-allocation stack-based code to arena-managed bulk operations and structured concurrency through actors. This enables developers to write everything from embedded firmware to high-performance services while preserving F#'s elegant syntax and type safety.
Central to Firefly's approach is the Program Semantic Graph (PSG) - a representation that combines syntactic structure with rich type information and optimization metadata. This enables comprehensive static analysis and allows the compiler to choose optimal memory strategies based on usage patterns.
Key Innovations:
- Flexible memory strategies from zero-allocation to arena-based management
- Deterministic resource management through RAII principles and compile-time tracking
- Type-preserving compilation maintaining F#'s rich type system throughout the pipeline
- Progressive lowering through MLIR dialects with continuous verification
- Platform-aware optimization adapting to target hardware characteristics
F# Source Code
β (F# Compiler Services parses & type-checks)
Type-checked AST + Symbol Information
β (PSG construction with semantic analysis)
Program Semantic Graph (PSG)
β (Memory strategy selection & optimization)
Memory-Optimized PSG
β (Transformation to MLIR operations)
MLIR High-Level Dialects
β (Progressive lowering through dialects)
Target-specific Dialects
β (Translation to LLVM IR or WAMI)
Native Binary or WebAssembly
Firefly operates as an intelligent compilation orchestrator that:
- Parses & analyzes - F# Compiler Services builds a fully type-checked AST
- Constructs PSG - Merges syntax tree with type information and semantic metadata
- Selects memory strategy - Chooses appropriate memory management based on usage patterns
- Transforms progressively - PSG β MLIR dialects β Target IR
- Optimizes aggressively - Platform-specific optimizations while preserving safety
- Verifies continuously - Memory safety and resource management guarantees
Unlike traditional approaches that force a single memory model, Firefly adapts to your code's needs:
For tight loops and performance-critical code, Firefly can compile to pure stack-based execution:
let processBuffer (data: Span<byte>) =
use buffer = stackBuffer<byte> 256
// All operations use stack memory
// No heap allocations, no GC pressure
data |> transformInPlace bufferWhen dynamic allocation is needed, arena-based management provides deterministic cleanup:
let processDataset records =
use arena = Arena.create 10_000_000 // 10MB arena
// All allocations within scope use the arena
// Bulk deallocation at scope exit - O(1) cleanup
records |> processWithArena arenaThe compiler automatically tracks resource lifetimes and inserts cleanup:
let processFile() = async {
let! file = File.openAsync "data.txt" // Compiler tracks this resource
let! data = file.readAsync()
return processData data
} // File automatically closed here - no explicit disposal neededIn development: The Olivier actor model will provide structured concurrency with per-actor memory arenas, enabling efficient message passing and isolated memory management for concurrent systems.
module HelloWorld
open Alloy.Console
[<EntryPoint>]
let main argv =
WriteLine "Hello, World!"
0module HelloWorldInteractive
open Alloy
open Alloy.Console
open Alloy.Memory
let hello() =
use buffer = stackBuffer<byte> 256
Prompt "Enter your name: "
let name =
match readInto buffer with
| Ok length -> buffer.AsSpan(0, length) |> toString
| Error _ -> "World"
WriteLine $"Hello, {name}!"
[<EntryPoint>]
let main argv =
hello()
0Compile with:
firefly compile HelloWorld.fidproj --output hello
./helloFirefly projects use ".fidproj" files with TOML configuration:
[package]
name = "my_app"
version = "1.0.0"
[compilation]
# Memory management strategy
memory_model = "mixed" # "zero_alloc" | "arena" | "mixed"
# Stack size for deterministic stack usage
max_stack_size = 4096
# Enable arena memory pools
enable_arenas = true
arena_default_size = 1_000_000
[optimization]
inline_threshold = 100
eliminate_closures = true # Convert to explicit parameters
[profiles.release]
lto = "full"
optimize = true# Build with default settings
firefly build
# Build with specific memory model
firefly build --memory-model zero_alloc
# Build for embedded target
firefly build --target thumbv7em-none-eabihf
# Analyze memory usage
firefly analyze --show-memory-layout- Deterministic memory management - No GC pauses, predictable performance
- Flexible memory strategies - Choose the right approach for each component
- Type and memory safety - Compile-time verification where possible
- Native performance - Direct compilation to machine code
- Async without allocations - Delimited continuations enable zero-allocation async
- Not purely stack-based - Uses appropriate memory strategies for different scenarios
- RAII over GC - Automatic but deterministic resource management
- Explicit when needed - Some patterns require explicit memory strategy choices
- Platform-aware - Different targets may use different memory implementations
- β Basic F# to MLIR pipeline
- β Stack memory operations
- π§ Arena memory management
- π§ RAII-based resource tracking
- π§ Async via delimited continuations
- π Linear types for zero-copy operations
- π Actor-based memory isolation (Olivier)
- π Cross-process memory coordination (Prospero)
- π Reference sentinels for distributed systems
- π WebAssembly via WAMI
- π Embedded ARM Cortex-M
- π GPU compute kernels
- π Hardware accelerator support
We will welcome contributions after establishing a solid baseline. Areas of particular interest:
- Memory optimization patterns - Novel approaches to deterministic memory management
- MLIR dialect design - Preserving F# semantics through compilation
- Platform targets - Backend support for new architectures
- Verification - Formal proofs of memory safety properties
Dual Apache 2.0 and Commercial License - see LICENSE for details.
- Don Syme and F# Contributors: For creating an elegant functional language
- MLIR Community: For the multi-level IR infrastructure
- LLVM Community: For robust code generation
- Rust Community: For demonstrating zero-cost abstractions in systems programming
- Fable Project: For showing F# can target alternative environments