Skip to content

Appendix A: Language Reference ​

Quick Reference ​

This appendix is your cheat sheet. When you forget syntax or need to look up a feature quickly, start here.

Keywords ​

fn          Function definition
struct      Structure definition
enum        Enumeration definition
type        Type alias
var         Mutable variable
const       Immutable variable
if          Conditional
else        Alternative branch
match       Pattern matching
while       Loop
for         Loop
break       Exit loop
continue    Skip iteration
return      Return from function
import      Import module
pub         Public visibility
spawn       Concurrent task
channel     Communication channel
some        Option variant
none        Option variant
ok          Result variant
err         Result variant

Operators ​

Arithmetic ​

wyn
+    Addition
-    Subtraction
*    Multiplication
/    Division
%    Modulo (remainder)

+ also concatenates strings, and it accepts an int on either side - the int is converted to its decimal text. This is intentional:

wyn
fn main() {
    print(5 + "x")     // 5x
    print("x" + 5)     // x5
}

float and bool are not converted; call .to_string() on those. For anything longer than a short label prefer ${} interpolation - see Strings.

Comparison ​

wyn
==   Equal
!=   Not equal
<    Less than
<=   Less than or equal
>    Greater than
>=   Greater than or equal

Logical ​

wyn
and   Logical AND
or    Logical OR
not   Logical NOT

Other ​

wyn
=    Assignment
.    Member access
::   Static access
?    Error propagation
[]   Indexing

Types ​

Primitive Types ​

wyn
int      64-bit integer
float    64-bit floating point
string   UTF-8 string
bool     Boolean (true/false)

Compound Types ​

wyn
[T]              Array of T
HashMap<K, V>    Hash map from K to V
Option<T>        Optional value (concrete: OptionInt, int?, ...)
ResultInt        Result-or-error (also ResultString, ResultFloat, ResultBool)

Type Syntax ​

wyn
var x: int = 42              // Explicit type
y = 42                   // Inferred type
const PI: float = 3.14159    // Constant with type

Variables ​

Declaration ​

wyn
mutable = 10        // Mutable
const immutable = 20    // Immutable

Scope ​

wyn
{
    inner = 10      // Scoped to block
}
// inner not accessible here

Shadowing ​

wyn
x = 5
x = x + 1          // Shadows previous x
var x = "hello"        // Can change type

Functions ​

Definition ​

wyn
fn function_name(param1: Type1, param2: Type2) -> ReturnType {
    // body
    return value
}

Examples ​

wyn
fn add(a: int, b: int) -> int {
    return a + b
}

fn greet(name: string) -> int {
    print("Hello, " + name)
    return 0
}

Generic Functions ​

wyn
fn identity<T>(x: T) -> T {
    return x
}

fn swap<T>(a: T, b: T) -> (T, T) {
    return (b, a)
}

Structs ​

Definition ​

wyn
struct StructName {
    field1: Type1,
    field2: Type2
}

Creation ​

wyn
var instance = StructName {
    field1: value1,
    field2: value2
}

Methods ​

wyn
fn StructName.method_name(self) -> ReturnType {
    return self.field1
}

Generic Structs ​

wyn
struct Container<T> {
    value: T
}

Enums ​

Definition ​

wyn
enum EnumName {
    VARIANT1,
    VARIANT2,
    VARIANT3
}

to_string ​

wyn
enum Color { Red, Green, Blue }
Color.Red.to_string()    // "Red"
c = Color.Blue
c.to_string()            // "Blue"

With Data ​

Variants can carry payloads:

wyn
enum Shape {
    Circle(int),
    Rect(int, int),
    Empty
}

Type parameters on your own enums (enum Result<T, E>) are not supported yet - the compiler rejects them. Option<T> and Result<T, E> are built in, so you get the two you actually need without declaring them:

wyn
fn find(k: int) -> Option<int> {
    if k > 0 { return Some(k) }
    return None
}

fn parse(s: string) -> Result<int, string> {
    if s.len() == 0 { return Err("empty") }
    return Ok(s.to_int())
}

fn main() -> int {
    match find(3) {
        Some(v) => print(v),
        None => print("none")
    }
    match parse("7") {
        Ok(n) => print(n),
        Err(e) => print(e)
    }
    return 0
}

Control Flow ​

If Statement ​

wyn
if (condition) {
    // true branch
} else if (other_condition) {
    // else if branch
} else {
    // else branch
}

While Loop ​

wyn
while (condition) {
    // body
}

For Loop ​

wyn
for (var i = 0; i < 10; i = i + 1) {
    // body
}

For-in Loop ​

wyn
for item in array { }
for i in 0..10 { }
for i, v in array { }   // indexed iteration

Match Expression ​

wyn
match value {
    pattern1 => action1,
    pattern2 => action2,
    _ => default_action
}

Pattern Matching ​

Literals ​

wyn
match x {
    0 => "zero",
    1 => "one",
    _ => "other"
}

Enums ​

wyn
match result {
    ok(value) => use_value(value),
    err(message) => handle_error(message)
}

Ranges and Or-Patterns ​

wyn
match n {
    1 | 3 | 5 => "odd",
    1..5 => "small (exclusive end)",
    1..=5 => "small (inclusive end)",
    _ => "other"
}

Guards ​

wyn
match n {
    _ if n < 0 => "negative",
    0 => "zero",
    _ => "positive"
}

Collections ​

Arrays ​

wyn
arr = [1, 2, 3, 4, 5]
arr[0]              // Access
arr.len()           // Length
arr.push(6)         // Append
arr.contains(3)     // Check membership

HashMaps ​

wyn
map = {"key1": 1, "key2": 2}
map["key1"]         // Access
map["key3"] = 3     // Insert
map.has("key1")     // Check key
map.remove("key2")  // Remove
map.len()           // Size

HashSets ​

wyn
set = {:"a", "b", "c"}
set.contains("a")   // Check membership
set.insert("d")     // Add
set.remove("b")     // Remove
set.len()           // Size

Error Handling ​

Result Type ​

wyn
fn operation() -> Result<int, string> {
    if (error_condition) {
        return Err("error message")
    }
    return Ok(42)
}

Option Type ​

wyn
fn find(arr: [int], target: int) -> Option<int> {
    // ...
    if (found) {
        return some(index)
    }
    return none
}

Error Propagation ​

wyn
fn chain() -> Result<int, string> {
    var x = operation1()?
    var y = operation2(x)?
    return Ok(y)
}

Modules ​

Import ​

wyn
import module_name
import path.to.module
import module as alias

Export ​

wyn
pub fn public_function() -> int {
    return 0
}

fn private_function() -> int {
    return 0
}

Extension Methods ​

Definition ​

wyn
fn TypeName.method_name(self) -> ReturnType {
    return self.field
}

Static Methods ​

wyn
fn TypeName.static_method() -> ReturnType {
    return value
}

Concurrency ​

Spawn ​

wyn
spawn function_call()           // fire and forget
var f = spawn function_call()   // keep a handle
var result = await f            // wait for the result

Channels ​

wyn
ch = channel(4)    // capacity 4
ch.send(42)
value = ch.recv()
ch.close()

Type Aliases ​

wyn
type UserId = int
type Email = string

Comments ​

wyn
// Single-line comment

// Multi-line comments use
// multiple single-line comments

String Escapes ​

wyn
"\n"    Newline
"\t"    Tab
"\\"    Backslash
"\""    Quote

Operator Precedence ​

From highest to lowest:

  1. Method call (.), indexing ([])
  2. Unary (not, -)
  3. Multiplication (*, /, %)
  4. Addition (+, -)
  5. Comparison (<, <=, >, >=)
  6. Equality (==, !=)
  7. Logical AND (and)
  8. Logical OR (or)
  9. Assignment (=)

Use parentheses to override precedence.

Common Patterns ​

Error Handling ​

wyn
match result {
    ok(value) => use_value(value),
    err(msg) => handle_error(msg)
}

Option Handling ​

wyn
match option {
    some(value) => use_value(value),
    none => use_default()
}

Iteration ​

wyn
for (var i = 0; i < arr.len(); i = i + 1) {
    process(arr[i])
}

Method Chaining ​

wyn
var result = text.trim().upper().reverse()

Naming Conventions ​

wyn
snake_case          Variables, functions
SCREAMING_SNAKE     Constants
PascalCase          Types (structs, enums)

File Extensions ​

.wyn    Wyn source file

Compilation ​

bash
wyn run program.wyn          # Compile and run
wyn build program.wyn        # Build a binary
./program                    # Run it
wyn help                     # Help

Common Mistakes ​

Leaving the Return Type Off ​

Wyn infers a return type from the return statements, so this compiles and returns an int:

wyn
fn add(a: int, b: int) {
    return a + b
}

Write it down anyway. It states the contract, and the checker then catches a body that drifts away from it instead of quietly changing the function's type:

wyn
fn add(a: int, b: int) -> int {
    return a + b
}

Parentheses in Conditions Are Optional ​

wyn
// Both are fine
if x > 0 { }
if (x > 0) { }

Ignoring Result/Option ​

wyn
// Wrong
var value = option  // Option<T>, not T

// Right
match option {
    some(value) => use_value(value),
    none => handle_none()
}

Forgetting pub ​

wyn
// Wrong (if you want it public)
fn helper() -> int { }

// Right
pub fn helper() -> int { }

Quick Examples ​

Hello World ​

wyn
fn main() -> int {
    print("Hello, World!")
    return 0
}

Read File ​

wyn
fn read_file(path: string) -> ResultString {
    if not File.exists(path) {
        return Err("file not found: " + path)
    }
    return Ok(File.read(path))
}

fn main() -> int {
    result = read_file("data.txt")
    match result {
        ok(contents) => print(contents),
        err(msg) => print("Error: " + msg)
    }
    return 0
}

HTTP Request ​

wyn
fn main() -> int {
    result = Http.get("https://api.example.com/data")
    match result {
        ok(response) => print(response.body),
        err(msg) => print("Error: " + msg)
    }
    return 0
}

Concurrent Tasks ​

wyn
fn producer(ch: int) -> int {
    Task.send(ch, 42)
    return 0
}

fn main() -> int {
    ch = channel(4)
    f = spawn producer(ch)

    value = ch.recv()
    print(value)

    await f
    return 0
}

This reference covers the essential syntax and patterns. For detailed explanations, see the main chapters. For complete API documentation, see Appendix B.

MIT License - v1.22.0