Skip to the content.

Fun Language Guide

This guide covers the syntax and features of the Fun programming language.

Table of Contents

Basic Syntax

Comments

# This is a single-line comment
# Comments start with # and continue to the end of the line

Expressions

Every expression in Fun evaluates to a value. Expressions can be:

Types

Basic Types

Integers

42          # positive integer
-17         # negative integer
0           # zero

Strings

`hello world`           # simple string
`Hello {name}!`         # string template with expression
`Value: {x + y}`        # string template with computation

String templates use curly braces {} to embed expressions.

Functions

Lambda Expressions

# Single parameter
inc = \x -> x + 1

# Multiple parameters
add = \x, y -> x + y

# No parameters (unit function)
const = \ -> 42

Function Application

# Direct application
inc(5)                  # result: 6
add(3, 4)               # result: 7

# Operator syntax for infix operators
3 + 4                   # same as +(3, 4)
10 == 5                 # same as ==(10, 5)

Higher-Order Functions

# Function that takes a function as parameter
apply_twice = \f, x -> f(f(x))

# Usage
apply_twice(inc, 5)     # result: 7 (inc(inc(5)))

Pattern Matching

When Expressions

Pattern matching is done with when expressions:

when value is
    Just x -> x;
    Nothing -> 0
else 42

Constructor Patterns

# Define a data type
data Maybe a = Just a | Nothing

# Pattern match on constructors
safe_head = \list ->
    when list is
        Cons head tail -> Just head;
        Nil -> Nothing

# Pattern match with payload binding
process_result = \result ->
    when result is
        Success value -> value;
        Error msg -> 0

Nested Patterns

# Pattern match on nested structures
process_nested = \data ->
    when data is
        Just (Cons x xs) -> x;
        Just Nil -> 0;
        Nothing -> -1

Records

Record Construction

# Simple record
person = {name: "Alice", age: 30}

# Record with expressions
point = {x: 10, y: 20, distance: sqrt(x*x + y*y)}

Record Access

person.name              # result: "Alice"
person.age               # result: 30
point.distance           # result: computed distance

Record Updates

# Create new record with updated field
older_person = {person | age: person.age + 1}

Record Types

# Type annotation for records
person : {name: Str, age: Int}
person = {name: "Bob", age: 25}

Lists

List Construction

# Empty list
empty = []

# List with elements
numbers = [1, 2, 3, 4, 5]

# List with expressions
squares = [x*x | x <- [1, 2, 3, 4, 5]]

List Operations

# Head and tail (pattern matching)
head = \list ->
    when list is
        Cons x xs -> x;
        Nil -> error "empty list"

# Length
length = \list ->
    when list is
        Cons x xs -> 1 + length(xs);
        Nil -> 0

Type Annotations

Explicit Types

# Function type annotation
factorial : Lam<Int, Int>
factorial = \n -> when n == 0 is
    True -> 1;
    False -> n * factorial(n - 1)

# Variable type annotation
count : Int
count = 42

Type Constructors

# Generic types
id : Lam<a, a>
id = \x -> x

# Complex types
map : Lam<Lam<a, b>, List<a>, List<b>>
map = \f, list -> when list is
    Cons x xs -> Cons (f x) (map f xs);
    Nil -> Nil

Type Variables

# Polymorphic functions
const : Lam<a, b, a>
const = \x, y -> x

# Type variables are lowercase
swap : Lam<a, b, {first: b, second: a}>
swap = \x, y -> {first: y, second: x}

Built-in Functions

Arithmetic

# Addition
5 + 3                    # result: 8

# Subtraction  
10 - 4                   # result: 6

# Comparison
5 == 5                   # result: True
3 == 7                   # result: False

Fixed-Point Combinator

# Recursion using fix
factorial = fix(\rec -> \n ->
    when n == 0 is
        True -> 1;
        False -> n * rec(n - 1)
)

Best Practices

Naming Conventions

# Variables and functions: lowercase with underscores
my_function = \x -> x + 1
user_name = "Alice"

# Constructors: start with uppercase
data Color = Red | Green | Blue

# Type variables: single lowercase letters
id : Lam<a, a>

Code Organization

# Group related functions together
# Math utilities
inc = \x -> x + 1
dec = \x -> x - 1
double = \x -> x * 2

# Export as record
{
    inc: inc,
    dec: dec,
    double: double
}

Error Handling

# Use Maybe types for optional values
safe_divide = \x, y ->
    when y == 0 is
        True -> Nothing;
        False -> Just (x / y)

# Use Result types for operations that can fail
parse_int = \str ->
    when str is
        "0" -> Success 0;
        "1" -> Success 1;
        _ -> Error "invalid number"

Common Patterns

List Processing

# Map over list
map = \f, list ->
    when list is
        Cons x xs -> Cons (f x) (map f xs);
        Nil -> Nil

# Filter list
filter = \pred, list ->
    when list is
        Cons x xs -> when pred(x) is
            True -> Cons x (filter pred xs);
            False -> filter pred xs;
        Nil -> Nil

Recursion

# Tail recursion with accumulator
factorial_tail = \n ->
    let
        fact_acc = \n, acc ->
            when n == 0 is
                True -> acc;
                False -> fact_acc(n - 1, n * acc)
    in
        fact_acc(n, 1)

This guide covers the essential syntax and features of Fun. For more advanced topics, see the Type System and Examples documentation.