Skip to content

Onion Programming Language

Build Status

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 / example clauses on a record are executed by the compiler at build time, so invariants like parse∘format == id are 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

Language Guide

Examples

Tools

Reference

Contributing

Design Notes

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:

  1. Parsing - JavaCC-generated parser produces untyped AST
  2. Rewriting - AST normalization and transformation
  3. Type Checking - Type inference, name resolution, overload resolution, and typed AST construction
  4. Tail-Call Optimization - Self-recursive loop lowering
  5. Mutual Recursion Optimization - State-machine lowering for @TailRecursive groups
  6. 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.