Fly
A programming language for writing easily and quickly all types of software.
import fly.os.io.*
void main() {
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.
Return values without the copy
Declare a return type before the function name.
Inside the body, assign to out — the implicit return variable.
In C++ you must choose: File f = open(path) (readable, but implies a copy)
or open(path, &f) (efficient, but noisy).
Fly does both with the same line — the source reads as return-by-value,
the compiler generates a hidden pass-by-reference.
Same LLVM output. Zero extra cost. No compromise on readability.
Read the Docs// return type declared in the signature
int calc(const int n) {
out = n * 2 // 'out' is the implicit return variable
}
void main() {
int x = calc(21) // x = 42 — ABI is hidden pass-by-reference
}
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"
}
}
void 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.
Plain new on a struct allocates on the stack —
freed automatically, no delete needed.
Plain new on a class allocates on the heap —
freed with delete, or use new unique /
new shared to let the compiler handle it.
struct Point {
int x
int y
}
interface Drawable {
draw()
}
class Circle : Point, Drawable {
int radius
draw() { /* render ... */ }
}
void 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
void 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