WORKS06 · 2026
← Works
ミドリ

Midori

A statically-typed functional language with algebraic data types, exhaustive pattern matching, typeclasses, and an explicit module system. Compiles to bytecode for the Midori Virtual Machine with mark-and-sweep garbage collection.

01Features
  • 01

    Static Type System

    Strong static typing with bidirectional inference, generics, constraints, and exhaustive checking.

    ·
  • 02

    Pattern Matching

    Exhaustive pattern matching on unions and Bool with compiler-enforced coverage.

    ·
  • 03

    Algebraic Data Types

    Express complex structures with structs, unions, type aliases, and recursive definitions.

    ·
  • 04

    Typeclasses

    Constrained generics with associated types and instance dispatch.

    ·
  • 05

    Modules & Packages

    Explicit imports/exports, project.midori layout, third-party packages with native FFI.

    ·
  • 06

    Typed Prelude

    MidoriPrelude exposes typed IO, system, date/time, text, and array helpers.

    ·
02Quick Start

A complete .mdr file starts with an explicit module declaration.

Hello World
module Main

import { "../MidoriPrelude/IO.mdr" }

IO::PrintLine("Hello, Midori!");
Functions
// Simple function
defun square(x: Int) : Int => {
    return x * x;
};

// Generic function
defun identity<T>(value: T) : T => value;

// Higher-order function
defun apply<T, R>(fn: fn(T) -> R, value: T) : R => {
    return fn(value);
};
Algebraic Data Types
// Product types (structs)
struct Point {
    x: Float,
    y: Float,
};

// Sum types (unions)
union Option<T> = None | Some(T);
union Result<T, E> = Ok(T) | Err(E);

def origin = new Point(0.0, 0.0);
def maybe = new Option::Some(42);
03Pattern Matching
Match Expression
union Result<T, E> = Ok(T) | Err(E);

defun handle_result<T>(result: Result<T, Text>) : Text => {
    return match result with
        case Result::Ok(value) => "Success: " ++ (value as Text)
        case Result::Err(msg) => "Error: " ++ msg
    ;
};
04Typeclasses

Constrained generics with associated types and instance dispatch — preserving static guarantees.

Show Typeclass
class Show<T> {
    show: fn(value: T) -> Text;
};

instance Show<Int> {
    defun show(value: Int) : Text => {
        return value as Text;
    };
};

defun display<T>(value: T) : Text where Show<T> => {
    return Show::show(value);
};
Associated Types
union Option<T> = None | Some(T);

class Iterable<Iter> {
    type Item;
    Next: fn(iter: Iter) -> Option<Item>;
};

defun NextValue<Iter>(iter: Iter)
    : Option<Iterable::Item<Iter>>
    where Iterable<Iter> => {
    return Iterable::Next(iter);
};
05Advanced
Pipe Into Match
defun double(x: Int) : Int => x * 2;
union Result<T, E> = Ok(T) | Err(E);

defun transform(value: Int) : Result<Int, Text> => {
    if value > 10
    then new Result::Ok(value + 1)
    else new Result::Err("too small")
};

def result =
    5
    |> double
    |> fn(x) => { x + 1 }
    |> transform
    |> match with
        case Result::Ok(value) => value
        case Result::Err(_) => 0;
Closures
defun make_counter() : fn() -> Int => {
    def count = 0;
    return fn() : Int => {
        count = count + 1;
        return count;
    };
};

def counter = make_counter();
def first = counter();   // 1
def second = counter();  // 2
06Typed Prelude

MidoriPrelude wraps the runtime FFI surface in Midori-facing modules. File and process APIs prefer typed Result and Option over sentinel returns.

Typed IO & System
module ConfigDemo

import
{
    "./MidoriPrelude/IO.mdr",
    "./MidoriPrelude/System.mdr",
    "./MidoriPrelude/Prelude/Option.mdr",
    "./MidoriPrelude/Prelude/Result.mdr"
}
use Option.{Option}
use Result.{Result}

def config_text =
    match IO::TryReadFile("app.conf") with
        case Result::Ok(contents) => contents
        case Result::Err(_) => "release=debug"
    ;

def cache_dir =
    match System::TryGetEnv("MIDORI_CACHE_DIR") with
        case Option::Some(path) => path
        case Option::None() => ".midori-cache"
    ;
07Standard Library
  1. 01IO.mdrConsole output and typed file APIs (TryReadFile, TryWriteFile, TryReadBinaryFile).
  2. 02System.mdrEnvironment, working-directory, process, and platform helpers using Option and Result.
  3. 03DateTime.mdrLocal and UTC date/time structs (LocalNow, UtcNow, FormatLocal).
  4. 04TextUtil.mdrText helpers — Length, Split, Replace, Trim, Reverse.
  5. 05ArrayUtil.mdrMutable array helpers — Append, Prepend, Extend, Slice, Reverse.
  6. 06Prelude/Result.mdrResult utilities built around Ok and Err with map, bind, and unwrap.
08Architecture
  1. 01FrontendLexer → Module Manager → Parser → Type Checker → Static Analyzer
  2. 02OptimizerConstant folding, strength reduction, closure lifting, tail-call optimization
  3. 03BackendBytecode generator → Linker
  4. 04RuntimeSingle VirtualMachine execution path with mark-and-sweep garbage collection
09Get Started
View on GitHubDocumentation ↗Try the Playground →