TypeReconstructable.jl is a Julia package for type-level programming and advanced metaprogramming. It provides a sophisticated system for encoding arbitrary values as types, enabling powerful compile-time computation patterns with zero runtime overhead.
- Type-Level Programming: Encode any serializable value as a type parameter using
TypeLevel{T,Buf}
- Reconstructable Types: Trait system for values that can be reconstructed from their types
- Generated Functions: Advanced
@gg_autogen
macro for GeneralizedGenerated.jl integration - Pattern Matching: MLStyle.jl integration for sophisticated AST and type pattern matching
- Scoping Analysis: JuliaVariables.jl integration for proper variable scoping and closure conversion
- Zero Runtime Overhead: All reconstruction happens at compile time through Julia's type system
using Pkg
Pkg.add("TypeReconstructable")
using TypeReconstructable
# Create a reconstructable value
rv = ReconstructableValue([1, 2, 3, 4, 5])
# The value is encoded in the type
T = typeof(rv) # ReconstructableValue{TypeLevel{Vector{Int64}, (...)}}
# Reconstruct the value from its type (happens at compile time)
reconstructed = reconstruct(T)
@assert rv.value == reconstructed.value # true
# Create generated functions that reconstruct values at compile time
@gg_autogen function process_data(x::ReconstructableValue{T}) where T
# This runs at compile time
val = reconstruct(typeof(x))
# Generate different code based on the reconstructed value
if val.value isa Vector
return quote
sum($(val.value)) + length($(val.value))
end
else
return quote
$(val.value) * 2
end
end
end
# Usage
data = ReconstructableValue([10, 20, 30])
result = process_data(data) # Compiles to: 60 + 3 = 63
# Pattern match on reconstructable types
@match_reconstructable rv begin
ReconstructableValue{TypeLevel{Vector{Int}, _}} => "Integer vector"
ReconstructableValue{TypeLevel{Dict{Symbol, _}, _}} => "Symbol dictionary"
_ => "Other type"
end
TypeReconstructable.jl abstracts sophisticated metaprogramming patterns from Soss.jl into a general-purpose library. The core idea is the "value that can be reconstructed from its type" pattern:
- Type-Level Encoding: Values are serialized and encoded as type parameters
- Compile-Time Reconstruction: Types can be "executed" to reconstruct their values
- Generated Functions: Julia's compilation system provides automatic memoization
- Pattern Matching: Sophisticated analysis and transformation of encoded types
src/typelevel.jl
: CoreTypeLevel{T,Buf}
encoding systemsrc/reconstructable.jl
:Reconstructable
trait andReconstructableValue
implementationsrc/gg_integration.jl
: Integration with GeneralizedGenerated.jl for advanced generated functionssrc/patterns.jl
: MLStyle.jl pattern matching utilities for TypeReconstructable typessrc/scoping.jl
: JuliaVariables.jl integration for scope analysis and closure conversionsrc/codegen.jl
: Macros and utilities for generated function creation
# Create your own reconstructable struct
@reconstructable struct MyModel
weights::Vector{Float64}
bias::Float64
end
# Usage
model = MyModel([1.0, 2.0, 3.0], 0.5)
T = typeof(model)
reconstructed_model = reconstruct(T) # Reconstructed at compile time
# Analyze variable scopes for metaprogramming
analyzer = ScopeAnalyzer()
mark_reconstructable!(analyzer, :my_var)
expr = :(x -> x + my_var)
analyzed, free_vars, reconstructable_vars = analyze_scope(expr, analyzer)
# Generate functions dynamically with proper scoping
@gg_autogen function create_function(expr_rv::ReconstructableValue{T}) where T
expr = reconstruct(typeof(expr_rv))
return quote
function generated_function(x)
$(expr.value)
end
end
end
The examples/
directory contains comprehensive demonstrations:
basic_usage.jl
: Core functionality and usage patternsadvanced_features.jl
: Sophisticated metaprogramming examples
Run examples with:
julia --project examples/basic_usage.jl
julia --project examples/advanced_features.jl
TypeReconstructable.jl provides zero runtime overhead through compile-time reconstruction:
# Runtime approach
function runtime_process(data)
if data isa Vector
return sum(data)
else
return 0
end
end
# Compile-time approach
@gg_autogen function compiletime_process(data::ReconstructableValue{T}) where T
val = reconstruct(typeof(data))
if val.value isa Vector
return quote
sum($(val.value)) # Inlined at compile time
end
else
return quote
0
end
end
end
The compile-time approach eliminates type checking and dispatch overhead by specializing code for each specific value.
TypeReconstructable.jl extracts and generalizes sophisticated metaprogramming patterns that were originally developed within Soss.jl for probabilistic programming. By factoring out these core techniques, they become available to the broader Julia ecosystem without domain-specific dependencies.
- Soss.jl: Probabilistic programming language where these patterns originated
- GeneralizedGenerated.jl: Advanced generated functions with closure support
- MLStyle.jl: Pattern matching for Julia
- JuliaVariables.jl: Variable scoping analysis
Contributions are welcome! Please see the development setup in CLAUDE.md
for detailed instructions on:
- Running tests:
julia --project test/runtests.jl
- Development commands and project structure
- Architecture and design decisions
This project is licensed under the MIT License - see the LICENSE file for details.