walnut/lang

There is no license information available for the latest version (0.0.12) of this package.

Installs: 24

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/walnut/lang

0.0.12 2025-08-02 12:41 UTC

This package is not auto-updated.

Last update: 2025-10-25 13:45:48 UTC


README

A strongly-typed, functional programming language for modeling and executing business logic with precision and clarity

Version License

Overview

Walnut is a modern functional programming language that combines powerful type system features with practical programming constructs. Designed for building robust applications, Walnut emphasizes type safety, immutability, and clear error handling while maintaining excellent developer ergonomics.

Key Features

  • 🎯 Expressive Type System - Set-theory based types with union, intersection, and refinement types
  • 🔒 Type Safety - Strong static type checking with comprehensive type inference
  • ⚡ Functional Core - Immutability by default with first-class functions and lambda expressions
  • 💉 Built-in Dependency Injection - Compile-time dependency resolution and service management
  • 🛡️ Sophisticated Error Handling - Result types with automatic error propagation
  • 🔧 Method-Oriented Design - Behavior-driven functions attached to types
  • 📦 Module System - Package-based organization with explicit dependency management
  • 🌐 JSON Integration - First-class support for JSON parsing and type-safe hydration

Quick Start

Installation

Install Walnut via Composer:

composer require walnut/lang

Hello World

Create a file hello.nut:

module hello:

>>> 'Hello, World!';

Run it from PHP:

php -f cli/index.php hello

Language Highlights

Powerful Type System

Walnut features one of the most expressive type systems among programming languages:

/* Refined types with constraints */
Age := Integer<0..150>;
Email := String<5..254> @ InvalidEmail :: /* Custom email validation */;
NonEmptyStringArray := Array<String, 1..>;

/* Union types in different forms */
MyResult := [status: String['success'], data: Any]
        | [status: String['error'], message: String];

/* Sealed types for data integrity */
User := $[id: Integer<1..>, name: String<1..>, email: Email];

/* Enumerations with pattern matching */
Status := (Pending, Active, Completed);

Functional Programming

First-class functions, immutability, and powerful transformation operations:

/* Lambda functions with named parameters */
double = ^x: Integer => Integer :: x * 2;

/* Array transformations */
numbers = [1, 2, 3, 4, 5];
doubled = numbers->map(double);
evens = numbers->filter(^i: Integer => Boolean :: i % 2 == 0);

/* Function composition */
processData = ^data: Array<Integer> ::
    data->filter(^x: Integer => Boolean :: x > 0)
        ->map(^x: Integer :: x * 2);

processed = processData([0, 1, -2, 3, -4, 5]);
/* Result: [2, 6, 10] */

Error Handling with Result Types

Type-safe error handling without exceptions:

Age = Integer<0..150>;

/* Result type for operations that may fail */
parseAge = ^input: String => Result<Age, NotANumber|String> :: {
    num = input => asInteger;  /* Propagates NotANumber error automatically */
    ?whenTypeOf(num) is {
        `Age: num,
        ~: => @'Age must be between 0 and 150'
    }
};

/* Pattern matching on results */
result = parseAge('25');
?whenIsError(result) { 'Could not parse age: ' + result->printed };

Method-Oriented Design

Attach behavior to types with methods:

/* Type definition */
Point := [x: Real, y: Real];

/* Methods on Point */
Point->distanceTo(^p: Point => Real<0..>) :: {
    dx = $x - p.x;
    dy = $y - p.y;
    dxSquared = dx * dx;
    dySquared = dy * dy;
    sum = dxSquared + dySquared;
    sum->sqrt
};

Point->translate(^delta: [dx: Real, dy: Real] => Point) :: {
    Point![x: $x + delta.dx, y: $y + delta.dy]
};

/* Usage */
p1 = Point![x: 0.0, y: 0.0];
p2 = Point![x: 3.0, y: 4.0];
distance = p1->distanceTo(p2);  /* 5.0 */
translated = p1->translate([dx: 1.0, dy: 2.0]);  /* [x: 1.0, y: 2.0] */

Type-Safe JSON Hydration

Convert external data to typed values with validation:

/* Define your data structure */
Email := #String<5..254> @ InvalidEmail :: /* Custom email validation */;
UserInput := $[
    username: String<3..20>,
    email: Email,
    age: Integer<13..>
];

/* Hydrate from JSON with automatic validation */
jsonData = '{"username":"alice","email":"alice@example.com","age":25}';
result = jsonData->jsonDecode => hydrateAs(`UserInput);

?whenIsError(result) {
    'Hydration failed: ' + result->printed
} ~ { 
    processUser(result)
};

Built-in Dependency Injection

Every function or method can declare dependencies that are automatically resolved at compile time:

/* The type to be injected */
ProjectById = ^ ~ProjectId => Result<Project, ProjectNotFound>;

/* Injected implementation */
==> ProjectById %% db: DatabaseConnection :: ... use db to fetch project ... ;

/* Using the injected function */
markProjectDone = ^id: ProjectId => Result<Null, ProjectNotFound> %% byId: ProjectById :: {
project = byId=>invoke(id); /* injected function called */
project->markDone;
...
};

Documentation

Walnut comes with comprehensive documentation organized into 5 major parts:

📚 Complete Language Specification

Part I: Fundamentals

Part II: Type Definitions

Part III: Functions, Methods, and Control Flow

Part IV: Built-in Library

Part V: Advanced Features

Examples

Web Service Example

module user-service %% $http/router, $db/connector:

User := $[id: Integer<1..>, username: String<3..20>, email: String];

createUser = ^[username: String, email: String] => *Result<User, String> :: {
    /* Validate input */
    ?when(#username->length < 3) {
        => @'Username too short'
    };

    /* Insert into database */
    sql = 'INSERT INTO users (username, email) VALUES (?, ?)';
    %databaseConnector |> execute(sql);

    /* Return created user */
    User[id: 1, username: #username, email: #email]
};

handleRequest = ^{HttpRequest} => {HttpResponse} :: {
    request = $->shape(`HttpRequest);

    ?whenValueOf(request.method) is {
        HttpRequestMethod.post: {
            userData = request.body->jsonDecode => hydrateAs(`[username: String, email: String]);
            result = createUser[username: userData.username, email: userData.email];

            ?whenTypeOf(result) is {
                `User: HttpResponse[status: 201, headers: [:], body: result->jsonStringify],
                `Error: HttpResponse[status: 400, headers: [:], body: [error: result->error]->jsonStringify]
            }
        },
        ~: HttpResponse[status: 405, headers: [:], body: 'Method not allowed']
    }
};

Data Processing Pipeline

module analytics:

Transaction := [id: Integer, amount: Real, category: String];

analyzeTransactions = ^transactions: Array<Transaction> :: {
    total = transactions->map(^t: Transaction => Real :: t.amount)->sum;

    /* Get unique categories */
    categories = transactions->map(^t: Transaction => String :: t.category)->unique;

    /* Calculate total per category */
    categoryTotals = categories->map(^cat: String :: [
        category: cat,
        total: transactions
            ->filter(^t: Transaction => Boolean :: t.category == cat)
            ->map(^t: Transaction => Real :: t.amount)
            ->sum
    ]);

    [total: total, byCategory: categoryTotals]
};

>>> {
    transactions = [
        [id: 1, amount: 100.0, category: 'food'],
        [id: 2, amount: 50.0, category: 'transport'],
        [id: 3, amount: 75.0, category: 'food']
    ];

    result = analyzeTransactions(transactions);
    result->printed
    /* Output: [total: 225.0, byCategory: [...]] */
};

Resources

Project Structure

walnut-lang/
├── cli/                      # CLI entry point
├── core-nut-lib/            # Core standard library (Walnut code)
├── docs/                    # Complete language documentation
│   ├── 00-index.md         # Documentation index
│   ├── 01-lexical-structure.md
│   ├── ...
│   └── 27-templates.md
├── src/                     # PHP implementation
├── walnut-src/             # Example Walnut programs
└── tests/                  # Test suite

Philosophy

Walnut is designed around several core principles:

  1. Type Safety First - Catch errors at compile time, not runtime
  2. Immutability by Default - Predictable, side-effect-free code
  3. Explicit Over Implicit - Clear intent and dependencies
  4. Business Logic Focus - Express domain models precisely
  5. Developer Ergonomics - Concise syntax without sacrificing clarity

Contributing

Contributions are welcome! Please feel free to submit pull requests, report bugs, or suggest features through the issue tracker.

License

Walnut Language is open-source software licensed under the MIT license.

Acknowledgments

Walnut draws inspiration from functional languages like Haskell and ML, type systems from TypeScript and Flow, and practical features from modern languages like Rust and Kotlin.

Ready to start? Check out the Complete Documentation or try the Online Demos!