Ball is a programming language where every program is a Protocol Buffer message. Write your logic once — serialize it, store it, send it over the wire, and compile it to any target language.
name: hello_world
modules:
-
name: main
functions:
-
name: main
body:
call:
module: std
function: print
input:
messageCreation:
typeName: PrintInput
fields:
-
name: message
value:
literal:
{ stringValue: Hello, World! }
metadata:
{ kind: function }
moduleImports:
-
{ name: std }
entryModule: main
entryFunction: main
POWERED BY
Ball takes a fundamentally different approach to programming languages. Instead of text files parsed into ASTs, your code starts as structured data.
Every Ball program is a Protocol Buffer message. If it deserializes, it’s structurally valid. No syntax errors, ever.
One Ball program compiles to Dart, C++, Python, Go, JavaScript, Java, C#, and more. Write once, target everything.
Programs are data. Serialize them to binary protobuf, store in databases, send over gRPC, or inspect programmatically.
Ball uses protobuf’s own DescriptorProto types, already mapped to every language. No type system fragmentation.
Every function takes one input message and returns one output message, like gRPC. This isn’t a limitation — it IS the design.
Encode Dart or C++ to Ball, then compile back. Metadata preserves visibility, annotations, and cosmetic details for perfect round-trips.
For each target language, Ball needs three components to achieve full support.
Parses native source code (Dart, C++, etc.) and encodes it into Ball protobuf messages. The Dart encoder uses the analyzer package; the C++ encoder uses Clang’s JSON AST.
Generates native source code from Ball protobuf messages. Handles expression trees, base function dispatch, type emission, and lazy evaluation for control flow.
Interprets Ball programs directly at runtime without compilation. Evaluates expressions, manages scopes, and dispatches base functions to native implementations.
The same Ball program compiles to idiomatic code in each target language.
name: fibonacci
inputType: int
outputType: int
body:
block:
statements:
-
expression:
call:
module: std
function: if
input:
messageCreation:
typeName: ""
fields:
-
name: condition
value:
call:
module: std
function: lte
input:
messageCreation:
typeName: ""
fields:
-
name: left
value:
reference:
{ name: n } -
name: right
value:
literal:
{ intValue: "1" } -
name: then
value:
call:
module: std
function: return
input:
messageCreation:
typeName: ""
fields:
-
name: value
value:
reference:
{ name: n }
result:
call:
module: std
function: add
input:
messageCreation:
typeName: ""
fields:
-
name: left
value:
call:
function: fibonacci
input:
call:
module: std
function: subtract
input:
messageCreation:
typeName: ""
fields:
-
name: left
value:
reference:
{ name: n } -
name: right
value:
literal:
{ intValue: "1" } -
name: right
value:
call:
function: fibonacci
input:
call:
module: std
function: subtract
input:
messageCreation:
typeName: ""
fields:
-
name: left
value:
reference:
{ name: n } -
name: right
value:
literal:
{ intValue: "2" }
metadata:
kind: function
params:
-
name: n
type: int
int fibonacci(int n) {
if ((n <= 1)) {
return n;
}
return (fibonacci((n - 1)) + fibonacci((n - 2)));
}
void main() {
final result = fibonacci(10);
print(result.toString());
}
Ball targets multiple languages at different maturity levels.
Full compiler, encoder, engine. Reference implementation.
Full compiler, encoder (Clang AST), engine. Actively developed.
Proto bindings generated. Compiler, encoder, and engine planned.
Proto bindings generated. Implementation in future roadmap.
Proto bindings generated. Web-first target language.
Proto bindings generated. Enterprise target language.
Proto bindings generated. .NET ecosystem target.
Every Ball computation is one of seven expression types. This uniform representation makes programs inspectable and transformable.
call
Invoke any function: {module, function, input}
literal
int, double, string, bool, bytes, or list literals
reference
Reference a bound name; "input" = function parameter
fieldAccess
Read a field from an object: {object, field}
messageCreation
Build a protobuf message: {typeName, fields[]}
block
Sequential let-bindings + result expression
lambda
Closures and inline function definitions
Ball is open source and actively developed. Get started with the Dart implementation today.
# Clone and get started
git clone https://github.com/Ball-Lang/ball.git
cd ball/dart && dart pub get
cd engine && dart test
# Compile an example
cd ../compiler
dart run bin/compile.dart ../../examples/hello_world.ball.json