Onion Programming Language¶
Onion is a statically-typed, object-oriented programming language that compiles to JVM bytecode. It combines the power of static typing with a concise, expressive syntax and seamless Java interoperability.
Key Features¶
- Statically Typed - Catch errors at compile time with local type inference
- Null Safety - Nullable types (
T?), safe calls (?.) and indexing (?[]), Elvis (?:), non-null assertion (!!), smart casts, and nullable-aware generics - Data Types - Records (generic, destructurable), data-carrying enums, and exhaustiveness-checked pattern matching over sealed hierarchies
- Bidirectional Records - One
record ... from re"..." derive!(Json, Yaml)declaration derives parse/format and JSON/YAML serde in both directions - Compile-Time Specs -
law/exampleclauses on a record are executed by the compiler at build time, so invariants likeparse∘format == idare machine-checked - Concise Classes - Primary constructors:
class Point(val x: Int, val y: Int) - Object-Oriented - Classes, inheritance, interfaces, and method overloading
- Functional Elements - Lambda expressions, closures, and first-class functions
- Monadic Composition - Do notation for Option, Result, and Future types
- Asynchronous Programming - Built-in Future type with functional combinators
- Java Interoperability - Direct access to Java libraries and frameworks
- JVM Target - Compiles to efficient JVM bytecode
- Concise Syntax - Clean, readable code with trailing lambda support
Quick Example¶
// Hello World
println("Hello, World!")
// Class definition with inheritance
class Calculator : JFrame <: ActionListener {
var result: Long
public:
def this {
// Constructor logic
this.result = 0L;
}
def calculate(x: Long, y: Long): Long {
return x + y;
}
}
// Lambda expressions
val filter: String -> Boolean = (line: String) -> {
return line.startsWith("ERROR");
}
// Pattern matching with select
val value = 3
select value {
case 0, 1, 2:
println("Low")
case 3, 4, 5:
println("Medium")
else:
println("High")
}
// Do notation for monadic composition
val result: Option[Int] = do[Option] {
x <- parseNumber("42")
y <- parseNumber("10")
ret x + y
}
// Async programming with Future
val future: Future[String] = Future::async(() -> { return fetchData(); })
future.map { data => processData(data) }
.onSuccess { result => println(result) }
// Null safety with safe call operator
val name: String? = getUserName() // Nullable type
val upper: Object? = name?.toUpperCase() // Safe call - returns null if name is null
val display: String = name ?: "unknown" // Elvis operator for default value
Getting Started¶
- Installation Guide - Set up Onion on your system
- Hello World Tutorial - Your first Onion program
- Quick Start - Essential language features
Language Guide¶
- Overview - Language philosophy and design
- Basic Syntax - Variables, operators, and expressions
- Variables and Types - Type system and type annotations
- Null Safety - Nullable types (
T?) and safe call operator (?.) - Control Flow - if, while, for, foreach, select, and do notation
- Functions - Function definitions and lambda expressions
- Lambda Expressions - Closures and trailing lambda syntax
- Classes and Objects - Object-oriented programming
- Inheritance - Subclassing and interface implementation
- Collections - Lists, maps, and built-in pipelines
- Java Interoperability - Using Java libraries
- Scripting - re""/file"" literals, derive!, law/example, pipelines, auto-CLI
Examples¶
- Overview - Collection of example programs
- Basic Programs - Hello World, arrays, loops, I/O
- Object-Oriented Examples - Classes, inheritance, interfaces, delegation
- Functional Programming - Lambdas, closures, recursion, do notation, Future
- Scripting & CLI - Command-line arguments, process execution, file I/O
- JSON & HTTP - JSON/YAML parsing, HTTP client basics
- Async & Concurrency - Futures, async composition, do-notation
- Error Handling - Option, Result, validation patterns
Tools¶
- Compiler (onionc) - Compile Onion source files to .class files
- Script Runner (onion) - Run Onion scripts directly (compile and execute)
- REPL - Interactive REPL for experimentation
Reference¶
- Language Specification - Complete Onion language specification
- Standard Library - IO, Option, Result, Future, and more
- Compiler Architecture - How the compiler works
- Error Codes - Common compilation errors and fixes
- Compiler Internals - Tail call optimization
Contributing¶
- Development Guide - How to contribute to Onion
- Building from Source - Build the compiler from source
- Releasing - Release process
Design Notes¶
- Generics Design - Erasure-based generics design
- Parser Refactoring - Separating grammar from AST building
- Quality Bar - Measurable practical-quality indicators
Project History¶
Originally written in Java in 2005, Onion has been completely rewritten in Scala 3.3.7, with only the parser using JavaCC. The compiler follows a classic multi-phase architecture:
- Parsing - JavaCC-generated parser produces untyped AST
- Rewriting - AST normalization and transformation
- Type Checking - Type inference, name resolution, overload resolution, and typed AST construction
- Tail-Call Optimization - Self-recursive loop lowering
- Mutual Recursion Optimization - State-machine lowering for
@TailRecursivegroups - Code Generation - Direct typed-AST bytecode generation via ASM
Community¶
License¶
Onion is open source software. See LICENSE for details.
This software includes software developed by Apache Software Foundation.