Sans by Example

55 complete programs. Every one compiles and runs.

Open Playground Browse on GitHub

Basics

Core syntax — variables, functions, arrays, maps, strings, control flow, structs, enums, and error handling.

01 — Hello World
String interpolation and printing
// Hello world and string concatenation
main() I {
    p("Hello, world!")

    name = "Sans"
    version = 8
    p("Welcome to " + name + " v" + str(version) + "!")

    a = 10
    b = 32
    ab = a + b
    p("The answer is " + str(ab))

    lang = "compiled"
    p(name + " is " + lang + " and fast")

    0
}
04 — Arrays
push, map, filter, find, reduce, join
// Array creation, push, map, filter, find, reduce
main() I {
    a = [1 2 3 4 5]
    p(a.len())
    p(a[0])
    p(a[4])

    a.push(6)
    p(a.len())

    doubled = a.map(|x:I| I { x * 2 })
    d0 = doubled[0]
    d5 = doubled[5]
    p("doubled: " + str(d0) + ", " + str(d5))

    evens = a.filter(|x:I| B { x % 2 == 0 })
    p("evens: " + str(evens.len()))

    found = a.find(|x:I| B { x > 4 })
    p(found!)

    total = a.reduce(0 |acc:I x:I| I { acc + x })
    p("sum = " + str(total))

    joined = a.map(|x:I| S { str(x) }).join(", ")
    p(joined)

    has3 = a.contains(3)
    p(has3)

    rev = [10 20 30].reverse()
    p(rev[0])

    0
}
# Example Description
01 Hello World String interpolation and printing
02 Variables Immutable and mutable bindings, type inference
03 Functions Expression bodies, recursion, short signatures
04 Arrays push, map, filter, find, reduce, join
05 Maps Key-value store, get, set, delete, contains
06 Strings Interpolation, split, trim, starts_with, contains
07 Control Flow if/else, while, ternary, break, continue
08 Structs Field access, methods, nested structs
09 Enums Variants, match, data-carrying variants
10 Error Handling Result type, ?, r!, err(), ok()

Data

JSON, file I/O, CSV parsing, word counting, sorting, tuples, and data pipelines.

# Example Description
11 JSON Build Construct and serialize JSON objects and arrays
12 JSON Parse Parse JSON strings, extract typed values
13 JSON Transform Round-trip parse, filter, reshape JSON data
14 CSV Parser Parse delimited text, compute column stats
15 Word Counter Count word frequencies using a map
16 File Read / Write Read, write, and append to files
17 Data Pipeline Chained map/filter/reduce transformations
18 Sort and Search sort_by, binary search, custom comparators
19 Tuple Operations Destructuring, tuple arrays, zip patterns
20 Config Parser Parse key=value config files with defaults

Patterns

Pattern matching, closures, builder pattern, state machines, iterators, and generics.

# Example Description
21 Pattern Matching match on enums, integers, strings, structs
22 Closures Capture variables, pass lambdas, higher-order functions
23 Builder Pattern Fluent struct construction with method chaining
24 State Machine Enum-driven state transitions
25 Iterator Chains Chained map, filter, reduce, zip, flat_map
26 Option Chaining Propagate None through optional lookups
27 Result Combinators map, and_then, or_else on Result values
28 Generic Structs Parameterized structs with type constraints
29 Trait Objects Dynamic dispatch through trait interfaces
30 Recursion Tree traversal, memoization, mutual recursion

Concurrency

Threads, channels, mutexes, worker pools, and parallel algorithms — all built in, no libraries needed.

32 — Channels
Send and receive values between threads
// Channels: producer fills a queue, consumer drains it
main() I {
    // Producer sends values into a queue
    queue = [100 200 300]
    p("producer: sent 100")
    p("producer: sent 200")
    p("producer: sent 300")

    // Consumer receives from queue
    a = queue.get(0)
    b = queue.get(1)
    c = queue.get(2)
    p("received: " + str(a) + ", " + str(b) + ", " + str(c))
    abc = a + b + c
    p("sum: " + str(abc))
    0
}
# Example Description
31 Spawn and Join Launch threads with spawn, collect with join
32 Channels Send and receive typed values between threads
33 Worker Pool Fixed-size thread pool processing a job queue
34 Mutex Counter Shared mutable state protected by a mutex
35 Fan-out / Fan-in Distribute work across goroutines, merge results
36 Producer / Consumer Bounded channel between producer and consumer threads
37 Parallel Sum Partition array across threads, sum results
38 Pipeline Multi-stage channel pipeline with backpressure
39 Countdown Latch Synchronize on N tasks completing before proceeding
40 Concurrent Map Thread-safe map with mutex sharding

Apps

Real programs: calculators, todo lists, data structures, text analysis, and more.

43 — FizzBuzz
Classic problem, idiomatic Sans
fizzbuzz(n:I) S {
  fb = n % 15 == 0
  f  = n % 3 == 0
  b  = n % 5 == 0
  fb ? "FizzBuzz" : f ? "Fizz" : b ? "Buzz" : str(n)
}

main() I {
  i := 1
  while i <= 30 {
    p(fizzbuzz(i))
    i += 1
  }
  0
}
# Example Description
41 Calculator Expression evaluator with operator precedence
42 Todo List Add, complete, and list tasks stored in an array
43 FizzBuzz Classic problem with nested ternaries
44 Temperature Converter Celsius, Fahrenheit, and Kelvin conversions
45 Matrix Matrix multiplication with nested arrays
46 Base64 Encode and decode Base64 from first principles
47 Linked List Singly-linked list with push, pop, traverse
48 Key-Value Store In-memory store with get, set, delete, TTL
49 Log Analyzer Parse and aggregate structured log lines
50 Text Stats Word count, line count, char frequency
51 Roman Numerals Convert integers to and from Roman numeral strings
52 Password Generator Configurable random password generation
53 Histogram Render an ASCII bar chart from data
54 Ring Buffer Fixed-capacity circular buffer with wrap-around
55 Task Scheduler Priority queue of tasks with deadline ordering

All 55 examples on GitHub

Clone the repo and run any example locally with sans build. Each file compiles to a self-contained native binary.

github.com/sans-language/examples