Kai

A functional-first scripting language with static typing

588
Tests Passing
8
Core Types
27
Built-in Functions
v0.0.4.3
Current Version

Core Features

Static Typing & Inference

Static type inference with unification, occurs check, and generalized let-polymorphism for ints, bools, strings, functions, and data structures.

Clean Syntax

Haskell-like lambdas, `do { ... }` blocks, precedence, keywords, and multi-statement files with expression-only core.

Interactive I/O & Conversions

User input with `input`, readable effect sequencing via `do` blocks, type conversions (`parseInt`, `toString`, `show`), and practical examples including text analysis, CLI tools, and interactive workflows.

Comprehensive Testing

588 passing examples with property-based testing, script evaluation, CLI coverage, stress checks, and example smoke coverage.

Developer Experience

CLI with help, inline evaluation, file execution, --debug flag for development, and comprehensive documentation.

Module System

Import modules with `import ModuleName`, top-level definitions with `let` and `letrec`, mutual recursion support, circular import detection, explicit exports, and module resolution.

Quick Start

Install & Run

stack build && stack test
stack exec kai -- --help
stack exec kai -- -e "print (42 + 1)"
stack exec kai -- --debug -e "42 + 1"
stack exec kai -- path/to/script.kai
stack exec kai -- examples/text_analysis.kai
stack exec kai -- examples/calculator.kai

Install CLI

make install
export PATH="$HOME/.local/bin:$PATH"
kai tests/arithmetic.kai

Language Elements

Basic Types

42 -3 true false "hi" ()

Operators

+ - * / ++ == < > and or not

Control Flow

if condition then expr1 else expr2

Lambda Functions

\\x -> x + 1 \\f -> f 42

Let Bindings, Blocks & Wildcards

let x = 42 in x + 1 do { print "hello"; 42 } let _ = expensiveCall in 42 letrec factorial = \\n -> if n == 0 then 1 else n * (factorial (n - 1)) in factorial 5

Type Annotations & Conversions

let add : Int -> Int -> Int = \\x : Int -> \\y : Int -> x + y parseInt "42" toString 100 discard 42 show (42 + 3)

Data Structures

[1, 2, 3] (1, "hi", true) {a = 1, b = true} Just 42 Left "error"

List & String Functions

map filter foldl length reverse take drop zip split join trim replace strLength head tail null fst snd

Interactive I/O & File Operations

input print "Hello" readFile "path" writeFile "path" "content" args do { print "A"; print "B"; 42 }

Example Scripts & Patterns

Module-Based Text Analysis

import TextAnalysis let text = case args of [] -> "Kai examples should stay practical, typed, and honest." | path :: _ -> readFile path let summary = summarize text print ("Preview: " ++ summary.preview) case summary.firstLongWord of Just word -> print ("First long word: " ++ word) | Nothing -> print "First long word: none"

Validated CLI Scripts

let validateNames : [String] -> Either String [String] = \\cliArgs -> if null cliArgs then Left "Usage..." else Right cliArgs letrec greetAll : [String] -> Unit = \\names -> case names of [] -> print "All greetings sent." | name :: rest -> do { print ("Hello, " ++ name ++ "!"); greetAll rest } case validateNames args of Left message -> print message | Right names -> greetAll names

List Processing & Let Polymorphism

let report = {count = length numbers, evenCount = length (filter even numbers), total = foldl (\\acc -> \\n -> acc + n) 0 numbers, labels = zip numbers (map (\\n -> if n > 20 then "high" else "steady") numbers)} let tag = \\label -> \\value -> {label = label, value = value} show (tag "total" (report.total)) show (tag "status" "ready")

Interactive Input & Parsing

let parseSecret : [String] -> Int = \\cliArgs -> case cliArgs of value :: _ -> (case parseInt value of Just n -> n | Nothing -> 42) | [] -> 42 let promptGuess : Int -> String = \\attempt -> do { print ("Attempt " ++ toString attempt ++ ": enter a guess"); input } case parseInt guessText of Just guess -> ... | Nothing -> do { print "Please enter an integer."; loop secret attempt }

File I/O & Arguments

let outputPath = case args of path :: _ -> path | [] -> "kai_output.txt" let content = join "\n" ["Kai writes files", "Kai reads them back", "Kai keeps scripts typed"] do { writeFile outputPath content; print ("Wrote " ++ outputPath) } print ("Read back: " ++ replace "\n" " | " (readFile outputPath))

Wildcard Patterns

case Right {ok = true, message = "loaded"} of Right {ok = true, message = _} -> "status: success" | Left _ -> "status: failure" | Right _ -> "status: unexpected" case (42, "kai", true) of (_, name, true) -> "tuple for " ++ name | _ -> "tuple mismatch" case [1, 2, 3, 4] of _ :: _ -> "list has values" | [] -> "list is empty"

Type Safety Examples

1 + true // Type error: TypeMismatch TInt TBool
if 5 then 1 else 2 // Type error: ExpectedBool TInt

Current Limitations

Current Limitations

× No REPL for interactive experimentation
× No error recovery (one parse error stops execution)
× Integer-only arithmetic (no floating-point)
× No custom data types (only built-in types)
× No polymorphic recursion for recursively-defined functions

Current Status (v0.0.4.3) & v0.0.4.4 Focus

Expressions (Done)

Ints, bools, strings (with ++), arithmetic (with unary minus), comparisons, conditionals

Lambda Functions (Done)

First-class functions, closures, application

Strings & Print (Done)

String literals, concatenation, print statements, multi-statement files

Type System (Done)

Static type inference with unification and occurs check

Let Bindings (Done)

Variable bindings and recursive function definitions with letrec

Type Annotations & Conversions (Done)

Optional type annotations, parseInt/toString/show functions, interactive I/O, wildcards, sequencing

Data Structures (Done)

Lists, tuples, records, pattern matching, Maybe/Either error handling

Standard Library (Done)

List functions (map, filter, fold, zip), string functions (split, join, trim), 27 built-ins

Top-Level Definitions & Modules (Done)

Module system with imports, top-level let/letrec definitions, mutual recursion support

File I/O & Scripting (Done)

readFile, writeFile, command-line arguments, practical scripting capabilities

v0.0.4.4 Focus

REPL, custom data types, stronger pattern matching, and essential scripting stdlib work

Later Releases

Formatter, linter, IDE support, package manager, HTTP/JSON, and deeper optimization work