No description
Find a file
2026-05-18 23:13:12 -06:00
.cargo build: add cargo config for PyO3 compatibility 2026-05-18 01:29:08 -06:00
docs feat: implement enums (sum types) with unit, tuple, and struct variants 2026-05-17 00:06:53 -06:00
examples docs: add borrow conflict example for teaching error messages 2026-05-18 23:13:12 -06:00
src feat: enhance ownership error messages with teaching format 2026-05-18 23:13:12 -06:00
.gitignore chore: add build tools to gitignore 2026-05-18 18:18:44 -06:00
Cargo.toml ci: add and remove Forgejo release workflow 2026-05-18 16:35:19 -06:00
Cross.toml feat: implement dereference operator (*ref) 2026-05-18 23:13:12 -06:00
pyo3-cross-config.txt feat: implement dereference operator (*ref) 2026-05-18 23:13:12 -06:00
README.md docs: add deepwiki badge 2026-05-19 01:55:48 +00:00
thorn-macos-aarch64 feat: implement dereference operator (*ref) 2026-05-18 23:13:12 -06:00

Thorn

DeepWiki Documentation

A programming language where crossing ecosystem boundaries is a first-class operation.

Installation

Option 1: Download pre-built binary

Download the latest release for your platform from the releases page, then:

# Linux/macOS
chmod +x thorn-*
sudo mv thorn-* /usr/local/bin/thorn

# Or keep it local
mv thorn-* ~/.local/bin/thorn  # Make sure ~/.local/bin is in your PATH

Option 2: Build from source

cargo install --path .

Getting Started

# Install the thorn binary
cargo install --path .

# Run a program from anywhere
thorn run examples/basics/hello.thorn

That's it. No runtime installation, no virtual environments, no package managers.

Simple Example

print("Hello, Thorn!")

let name = "World"
print("Hello,", name)

Calling Python from Thorn

import foreign_py math from "math" {
    fn sqrt(x: f32) -> f32
    fn pow(x: f32, y: f32) -> f32
}

match math.sqrt(16.0) {
    Ok(result) => print("sqrt(16) =", result)
    Err(e) => print("Error:", e)
}

let value = math.pow(2.0, 10.0)?
print("2^10 =", value)

Foreign function calls automatically return Result<T, Error> for safe boundary crossing. Use ? to propagate errors.

Calling C from Thorn

import foreign_c math from "./libmath.dylib" {
    fn add(a: i32, b: i32) -> i32
}

match math.add(5, 3) {
    Ok(sum) => print("5 + 3 =", sum)
    Err(Error::C(c_err)) => {
        print("C error in", c_err.function)
        print("Library:", c_err.library)
    }
}

C functions work with basic types (integers, floats, strings, pointers). Support for 0-2 arguments currently.

Standard Library

let maybe = Some(42)
match maybe {
    Some(val) => print("Got:", val)
    None => print("Nothing")
}

let nums = [1, 2, 3, 4, 5]
print("Length:", nums.len())
let first = nums.get(0)

let map = HashMap::new()
    .insert("name", "Thorn")
    .insert("version", "0.1")
    .insert("status", "working")

print(map.get("name"))

Generic types: Option<T>, Result<T, E>, array methods, HashMap<K, V>.

Pattern Matching

struct Point { x: i32, y: i32 }

let point = Point { x: 0, y: 7 }

match point {
    Point { x: 0, y: 0 } => print("origin")
    Point { x: 0, y } => print("on y-axis at", y)
    Point { x, y: 0 } => print("on x-axis at", x)
    Point { x, y } => print("at", x, y)
}

enum Shape {
    Circle(f32),
    Rectangle { width: f32, height: f32 }
}

let shape = Shape::Circle(5.0)
match shape {
    Shape::Circle(r) => print("circle with radius", r)
    Shape::Rectangle { width, height } => print("rectangle", width, "x", height)
}

What Works

  • Variables and functions
  • Structs and enums with full pattern matching
  • Arrays with indexing and iteration
  • Generic types: Option<T>, Result<T, E>, HashMap<K, V>
  • Control flow: if, while, for, match
  • Python FFI with automatic Result wrapping
  • C FFI with automatic Result wrapping
  • Error propagation with ? operator
  • String interpolation
  • Method chaining
  • Interactive REPL with line editing and history

Test coverage: 91 tests passing

What Doesn't Work Yet

  • C FFI limited to 0-2 arguments and basic types
  • Python FFI doesn't support objects or methods
  • No WASM FFI
  • Type checker exists but boundary types not enforced
  • No compiler error improvements yet
  • No borrowing/ownership system
  • No generics beyond built-in types

Thorn is honest about its limitations. These are real constraints, not "coming soon."

Building from Source

# Install globally (recommended)
cargo install --path .

# Or build for development
cargo build

# Run tests
cargo test

# Development: run without installing
cargo run -- run examples/stdlib/option_basic.thorn

Examples

The examples/ directory contains working programs:

Basics:

  • hello.thorn - Hello world
  • calculator.thorn - Functions and arithmetic
  • demo.thorn - Comprehensive features

Standard Library:

  • stdlib/option_basic.thorn - Option usage
  • stdlib/vec_basic.thorn - Array methods
  • stdlib/hashmap_basic.thorn - HashMap operations

FFI:

  • ffi/c_ffi.thorn - Calling C functions
  • ffi/c_strings.thorn - String handling with C
  • ffi/python/python_basic.thorn - Python interop

Language Features:

  • match.thorn - Pattern matching
  • structs.thorn - Struct definitions
  • enums.thorn - Sum types
  • arrays.thorn - Collections

CLI Usage

# Run a program
thorn run <file.thorn>

# Check syntax and show AST
thorn check <file.thorn>

# Interactive REPL
thorn repl

Why Thorn Exists

Most languages pretend foreign code doesn't exist. When you need to call Python from Rust, or C from Go, you write FFI bindings in a separate layer with different error handling, different types, and different conventions.

Thorn makes boundaries visible and safe by default. Every foreign function returns Result<T, Error>. The error tracks origin (::c, ::python, ::wasm). Pattern matching lets you handle errors by source:

match call_foreign_function() {
    Ok(value) => use_value(value)
    Err(Error::Python(py_err)) => handle_python_error(py_err)
    Err(Error::C(c_err)) => handle_c_error(c_err)
}

This isn't a research language. It's for systems-aware builders working at ecosystem boundaries: game developers calling ML libraries, systems programmers using C APIs, engineers building polyglot systems.

Project Structure

ThornC/
├── src/
│   ├── lexer/         Tokenization
│   ├── parser/        AST generation
│   ├── ast/           AST definitions
│   ├── runtime/       Tree-walking interpreter
│   ├── typecheck/     Type checking (basic)
│   ├── interop/       FFI implementation (C, Python)
│   └── error/         Error types and handling
├── examples/          Working Thorn programs
└── docs/              Design documentation

Documentation

Contributing

Thorn is in active development. We welcome:

  • Bug reports and feature requests
  • Example programs showing real use cases
  • Design feedback on FFI ergonomics
  • Documentation improvements

Open an issue or submit a pull request.

Development Status

Current phase: Working prototype with FFI foundation

The core language works. Python and C FFI work for basic cases. The standard library has essential types. Pattern matching is complete. Tests pass.

What's next: expanding FFI capabilities, improving type checking at boundaries, better error messages.

License

MIT