Fly
A programming language for writing easily and quickly all types of software.
import fly.os
main() {
os.print("Hello, World!")
}
Fast
Built on LLVM, Fly compiles to optimised native code for all major platforms.
Simple
Clean, readable syntax designed to be easy to write and understand with no unnecessary complexity.
Powerful
Multi-paradigm with procedural, object-oriented, and functional programming support.
Zero-copy functions, by design
In Fly every parameter is always passed by reference — no copies, ever.
Mark a parameter const to declare it as a read-only input.
Leave it mutable and it becomes an output: the function writes results
directly into the caller's variables.
This keeps call overhead minimal and lets LLVM optimise aggressively, regardless of what you are passing.
Read the Docs// const = input (read-only reference)
// no const = output (written directly by the function)
calc(const int n, int result) {
result = n * 2
}
main() {
int x
calc(21, x) // x = 42
}
Error handling, rethought
Use fail to signal an error with an optional code and message.
Errors propagate automatically to the caller — no explicit rethrow needed.
Wrap calls in handle to capture any error into the
error variable, populated automatically.
Then branch on it to decide what to do.
get(const string url) {
if (url == "") {
fail 1, "url is empty"
}
}
main() {
handle {
get("")
}
if (error) {
// manage error ...
}
}
A clean object model
Fly has three distinct building blocks: struct for pure data,
class for objects with behaviour, and interface
for contracts.
A struct holds fields and can extend one other struct —
no virtual dispatch, no hidden cost.
A class adds virtual methods via vtable and can extend
a struct and implement multiple interfaces.
An interface defines method signatures only and can
extend multiple other interfaces.
Heap objects are created with new and released with
delete — or left to a smart pointer to handle automatically.
struct Point {
int x
int y
}
interface Drawable {
draw()
}
class Circle : Point, Drawable {
int radius
draw() { /* render ... */ }
}
main() {
Circle c = new Circle()
c.radius = 5
c.draw()
delete c
}
process() {
Point p = new unique Point()
p.x = 10
p.y = 42
} // ← p freed automatically here
main() {
process() // no leaks, no delete
}
Memory management, your way
Fly gives you three ownership models — no garbage collector, no runtime overhead.
new unique grants exclusive ownership: the object is freed automatically
when the variable goes out of scope.
new shared uses reference counting: the object lives as long as at least
one owner exists.
new weak leaves lifetime control to you, with no counting overhead.
All three are deterministic: memory is released exactly when the scope ends, with no pauses and no surprises.
Read the Docs