Quickstart

Learn the fundamentals of Weave in 10 minutes. General programming knowledge is assumed.

Variables and Types

# Comments start with #

# Variables are declared by assignment
name = "Alice"
count = 42
ratio = 3.14

# Numbers auto-convert between integer and float
half = count / 2    # 21.0

# Symbols are immutable constant strings, starting with ':'
status = :active
format = :json

Symbols are interned strings best used as keys and/or enum values. They’re lighterweight to pass around and compare vs regular strings, but more expensive to create initially than a unique string.

Strings

count = 42
greeting = "Hello, World!"

# String interpolation uses curly braces
message = "Count is: {count}"

# Concatenation with +
full = "Hello" + " " + "World"

Containers

Containers are Weave’s main (and only) data structure. Containers hold a list of values - and values can optionally have associated names.

Containers thus behave similar to both lists and maps from other languages.

# List-style
numbers = [1, 2, 3, 4, 5]
numbers[0]      # 1 (0-indexed)
numbers[-1]     # 5 (negative index from end)

# Map-style with key: value pairs
person = [name: "Bob", age: 30, active: true]
person[:name]   # "Bob"

# Mixed containers are valid
data = [1, 2, label: "test", 3]

# Append and add keys
numbers << 6
person[:email] = "bob@example.com"

Set Operations

a = [1, 2, 3]
b = [2, 3, 4]

a + b     # [1, 2, 3, 2, 3, 4]  concatenation
a | b     # [1, 2, 3, 4]        union
a & b     # [2, 3]              intersection
a - b     # [1]                 difference

Functions

fn add(a, b) {
    a + b    # last expression is returned implicitly
}

# Default parameters are supported
fn greet(name, greeting: "Hello") {
    greeting + ", " + name + "!"
}

greet("Alice")           # "Hello, Alice!"
greet("Bob", "Hi")       # "Hi, Bob!"

Lambdas

Lambdas are anonymous functions declared with ^:

double = ^(x) { x * 2 }
double(5)    # 10

# With a default parameter for accumulation
sum = ^(v, acc: 0) { acc + v }

Pipeline Operators

The three pipeline operators are the heart of Weave:

# |> pipe: pass a value on the left into a function on the right:
42 |> print          # prints 42

# *> map: apply a function to each element in a Container
[1, 2, 3] *> ^(x) { x * 2 }    # [2, 4, 6]

# &> reduce: accumulate values, applying the function to each element in a Container
sum = ^(v, acc: 0) { acc + v }
[1, 2, 3, 4] &> sum    # 10

Chain them together to build data pipelines:

read("sales.csv", :csv)
    *> ^(row) { row[:amount] }
    &> ^(v, acc: 0) { acc + v }
    |> print

File I/O

# Read structured data - common formats can be parsed implicitly
data = read("config.toml", :toml)
users = read("users.json", :json)
records = read("data.csv", :csv)

# Write formatted data back the same way
write("output.json", data, :json)

Shell Integration

# Run shell commands with backticks
result = `ls -la /var/log`

if result[:success] {
    split(result[:output], "\n")
        *> ^(line) { split(line, " ")[-1] }
        |> print
}

Next Steps

That’s the core of Weave! Explore the Learn Weave section for deeper coverage of each topic.