FAQ.md

December 12, 2025 · View on GitHub

How is this better than C?

  • This question depends heavily on the way in which you define "better". For performance, C is substantially better. For ease of use, Elle is progressing towards being better than C.

Feature list

What kind of...AnswerNotes
SyntaxC/Rust styleCan look like C or rust depending on the features used.
ParadigmProceduralFunctions can be values, but primarily the language is procedural
Memory managementGCGC by default, can become Arena by default, can be swapped to anything
TypingStaticThe language is strongly statically typed
MutabilityMutableAll variables are mutable, always
LifetimesN/AGC means the lifetime of objects is not explicitly managed by the developer
Compiler backendQBELLVM is too bloated for the language's needs, therefore QBE is used instead
Compilation modelAOTCompiled to native code (via QBE)
Target platformNative onlyOnly supports whatever platforms QBE supports, with WASM support planned
StringsNull terminatedTo be fully C ABI compliant, strings are null terminated and not sized
Extension.leHistory: .elle -> [.elle, .l] -> [.elle, .le] -> .le
LicenseGPL-3Since April 11th 2025 3:18 PM GMT+1
WrappingCurly onlyPrefers if x { y } rather than if (x) y (curly braces are mandatory)
LoopsStandardwhile cond {} or for x := 1; x < 10; x += 1 or for x in [1, 2, 3] or for x in 0..10
EnumsBasicNon-generic enums with an optional literal value, not tagged unions
NamespacesBasicFunctions and constants can be namespaced, but only 1 level deep
ModulesBasicModules do not automatically namespace anything
FeatureSupportNotes
Custom AllocatorsYesThe allocator can be changed at runtime, but must be GC or Arena by default.
Lambdas (Closures)PartialLambdas exist, but don't capture their surrounding scopes.
Pattern matchingNoSupport planned in the future.
Operator overloadingPartialCan overload x[y], &x[y], x[y] = z x == y, *x = y, as well as length, hash, tuple, triple, & iter.
First class functionsYesFunctions can be passed around, and their interface can be expressed in the type system.
Lazy IteratorsYesDue to QBE identifier length limitations, only 8-9 adapters can be chained at once. OK for most usecases.
GenericsPartialGeneric functions and structs exist, generic enums do not currently exist but are planned.
Type inferenceYesThe return type of functions is inferred. You can use let x = 1 or x := 1 to infer variable types.
ConcurrencyNoSupport planned in the future.
Maybe/OptionYesPointers can be nil, but an additional Option feature exists in the prelude.
Manual memory managementYesUse mem::malloc and mem::free to allocate without the GC, or use #set_allocator(HeapAllocator::new()).
CoroutinesNoSupport planned in the future.
Rich errorsYesElle has a built-in type Result<T, E> in the prelude with helper methods, similar to Rust.
Macros/metaprogrammingPartialConstants act as macros in a way, they will be recreated each time they're referenced.
Modules/namespacesPartialFunctions and constants can be namespaced but only 1 level deep. Modules exist but do not qualify imports.
Tail call optimizationNoSupport planned in the future.
C FFIYesAll C code is callable directly within Elle and vice versa.
Fast compilation timesPartialAll projects should compile < 1s, but it is being constantly improved.
LSPPartialYes, but only for Zed. A language client extension doesn't exist for editors like nvim or vscode yet.
Standard formatterNoSupport planned in the future.
GC TuningNoSupport planned in the future.
Standard libraryPartialA standard library exists but is lacking features and documentation.
IntrospectionPartialOnly introspection at runtime of function call metadata at the call site, structs cannot be reflected.
DeferringYesCurrently slightly broken, but should not affect most use-cases.