Everything you need to understand, build, and extend the Ball programming language.
Ball is a programming language where every program is a Protocol Buffer message. Instead of text files that are parsed into ASTs, your code starts as structured data β a protobuf message that can be serialized, stored in databases, sent over gRPC, inspected, transformed, and compiled to any target language.
The language schema is defined in a single file: proto/ball/v1/ball.proto. This proto file is the canonical source of truth for what a valid Ball program looks like.
Every function takes a single input message and returns a single output message, following the gRPC pattern. This is not a limitation β it IS the design. Multiple parameters are expressed as fields of the input message.
The entire AST β expression tree, modules, functions, types β is defined in ball.proto. Programs can be serialized to binary protobuf or JSON. If it deserializes, itβs structurally valid.
The expression tree, function signatures, type descriptors, and module structure are semantic. Everything else (visibility, mutability, annotations, syntax sugar) is cosmetic metadata. A Ball program with all metadata stripped computes the same result.
Base functions are declared with isBase: true and have no body expression. Their implementation is provided by each target languageβs compiler/engine. This is the extensibility mechanism.
if, for, while, switch, try β theyβre all std base functions. This keeps the language uniform. Compilers must handle them with lazy evaluation (donβt evaluate all branches before choosing one).
Ball does NOT invent its own type system. It uses google.protobuf.DescriptorProto and FieldDescriptorProto, which already define how types map to every target languageβs native types.
A Ball program is a Program protobuf message that contains modules, which contain functions, types, constants, and imports.
Program
βββ name, version, entryModule, entryFunction
βββ modules[]
βββ name, description
βββ types[] (google.protobuf.DescriptorProto)
βββ typeDefs[] (TypeDefinition)
βββ typeAliases[] (TypeAlias)
βββ enums[] (google.protobuf.EnumDescriptorProto)
βββ moduleConstants[] (Constant)
βββ functions[] (FunctionDefinition)
βββ moduleImports[] (ModuleImport)
Every Ball computation is one of seven expression types. This is the core of the language:
| Expression | Meaning | Example |
|---|---|---|
call |
Function call | {module, function, input} |
literal |
Constant value | int, double, string, bool, bytes |
reference |
Variable reference | "input" = function parameter |
fieldAccess | Field access | {object, field} |
messageCreation |
Construct message | {typeName, fields[]} |
block |
Statement block | let-bindings + result expression |
lambda | Anonymous function | Closures |
Blocks contain Statements (either LetBinding or bare Expression) followed by a result expression. LetBindings bind a name to a value with optional metadata (type, mutability: var/final/const).
Ball comes with a comprehensive standard library. All standard library functions are base functions β their implementation is provided by each target language.
| Module | Functions | Description |
|---|---|---|
std |
~120 | Arithmetic, comparison, logic, bitwise, string, math, control flow, type ops |
std_collections | ~43 | List and Map operations |
std_io | ~10 | Console, process, time, random, environment |
std_memory | ~30 | Linear memory (C/C++ interop) |
dart_std |
~18 | Dart-specific: cascade, null_aware_access, invoke, spread |
Ball supports resolving dependencies from four source types:
Each import supports a SHA-256 integrity hash for supply-chain security.
All metadata is cosmetic β it improves round-trip fidelity but doesnβt change computation. Key metadata fields include:
Clone the repository and try the Dart implementation:
# Clone Ball
git clone https://github.com/Ball-Lang/ball.git
cd ball
# Install Dart dependencies
cd dart && dart pub get
# Run the engine tests
cd engine && dart test
# Compile an example to Dart
cd ../compiler
dart run bin/compile.dart \
../../examples/hello_world.ball.json
# Build the C++ implementation
cd ../../cpp/build && cmake .. && cmake --build .
The proto schema is published on Buf: buf.build/ball-lang/ball