Examples

Learn Sigil through real-world code examples. Each example demonstrates key concepts and best practices.

Hello World

The simplest Sigil program:

fn main() {
    let message! = "Hello, World!"
    println(message)
}

Note the ! marker — it indicates that message is known data (computed locally).

Evidentiality Basics

Sigil tracks where data comes from. Here's how evidence markers propagate:

// Known: computed locally
let local! = 42

// Reported: from external source
let external~ = api.fetch("/data")

// Uncertain: might be absent
let maybe? = database.find(id)

// Combining evidence levels
let result~ = local + external  // ! + ~ = ~

// Validation promotes evidence
let trusted! = external |validate!{ verify_signature() }

Morpheme Operators

Greek letter operators for data transformation:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// Filter (φ), transform (τ), reduce
let result = numbers
    |φ{. % 2 == 0}     // keep even: [2, 4, 6, 8, 10]
    |τ{. * 2}           // double:    [4, 8, 12, 16, 20]
    |Σ                   // sum:       60

// Sort (σ)
let sorted = users |σ·by{.name}

// First (α) and last (ω)
let first? = users |α
let last? = users |ω

Safe API Client

A type-safe HTTP client that enforces validation of external data:

struct User {
    id: Uuid,
    name: Str,
    email: Email,
    role: Role,
}

struct ApiClient {
    base_url: Url!,
    auth_token: Str!,
}

impl ApiClient {
    // Returns reported data - caller must validate
    async fn get_user(&self, id: Uuid) -> Result<User~> {
        let response~ = http::get("{self.base_url}/users/{id}")
            .header("Authorization", "Bearer {self.auth_token}")
            .await?;

        let user~: User~ = response.json()?;
        Ok(user)
    }

    // Returns validated data - safe to use
    async fn get_verified_user(&self, id: Uuid) -> Result<User!> {
        let user~ = self.get_user(id).await?;

        // Validate all fields
        let verified! = user |validate!{
            .id.is_valid() &&
            .name.len() > 0 &&
            .email.is_valid() &&
            .role.is_known()
        };

        Ok(verified)
    }
}

// Usage
async fn process_user(client: &ApiClient, id: Uuid) {
    // This won't compile - can't use reported data directly
    // let user~ = client.get_user(id).await?;
    // database.insert(user);  // ERROR: expected User!, got User~

    // This works - data is verified
    let user! = client.get_verified_user(id).await?;
    database.insert(user);  // OK: User!
}

Form Validation

Safe handling of user input with progressive validation:

struct RegistrationForm {
    email: Str,
    password: Str,
    confirm_password: Str,
}

struct ValidatedRegistration {
    email: Email!,
    password_hash: Hash!,
}

fn validate_registration(form: RegistrationForm~) -> Result<ValidatedRegistration> {
    // All form data is reported (user input)
    let email~ = form.email;
    let password~ = form.password;
    let confirm~ = form.confirm_password;

    // Validate email format
    let valid_email? = email |validate?{ Email::parse(.) };
    let email! = valid_email.ok_or(Error::InvalidEmail)?;

    // Validate password requirements
    let password! = password |validate!{
        .len() >= 12 &&
        .contains_uppercase() &&
        .contains_number() &&
        . == confirm
    }.ok_or(Error::WeakPassword)?;

    // Hash password (produces known data)
    let hash! = crypto::hash(password);

    Ok(ValidatedRegistration {
        email,
        password_hash: hash,
    })
}

Data Pipeline

Processing data from multiple sources with evidence tracking:

struct SalesReport {
    total: Decimal,
    by_region: Map<Region, Decimal>,
    confidence: Float,
}

async fn generate_report(date_range: DateRange!) -> SalesReport! {
    // Fetch from multiple sources (all reported)
    let db_sales~ = database.query_sales(date_range).await;
    let api_sales~ = external_api.get_sales(date_range).await;
    let csv_sales~ = import_csv("manual_entries.csv").await;

    // Validate each source
    let db_validated! = db_sales |validate!{ verify_db_integrity(.) };
    let api_validated? = api_sales |validate?{ verify_api_response(.) };
    let csv_validated? = csv_sales |validate?{ verify_csv_format(.) };

    // Merge with evidence-aware aggregation
    let all_sales = [db_validated, api_validated, csv_validated]
        |φ{.is_some()}
        |τ{.unwrap()};

    // Calculate totals
    let total! = all_sales |τ{.amount} |Σ;

    let by_region! = all_sales
        |group_by{.region}
        |τ{(region, items) => (region, items |τ{.amount} |Σ)};

    // Confidence based on data completeness
    let sources_valid = [api_validated.is_some(), csv_validated.is_some()];
    let confidence! = 0.6 + (sources_valid |φ{.} |count) * 0.2;

    SalesReport { total, by_region, confidence }
}

Simple Agent

A basic agent with tool use:

agent Calculator {
    execution: Daemon {
        tools: [Tool::Calculator],
    }
}

impl Calculator {
    fn process(&self, query: Str~) -> Result<Str!> {
        // Parse expression (reported input)
        let expr? = Expression::parse(query)?;

        // Evaluate (produces known result)
        let result! = self.tools.calculator.eval(expr);

        Ok("Result: {result}")
    }
}

Agent with Memory

An agent that remembers past interactions:

agent PersonalAssistant {
    memory: Engram {
        instant: 4096,
        episodic: true,
        semantic: true,
    },
    learning: Gnosis {
        adaptation_rate: 0.1,
    }
}

impl PersonalAssistant {
    async fn respond(&mut self, message: Str~) -> Str! {
        // Check for similar past interactions
        let context? = self.engram.episodic
            |φ{.similarity(message) > 0.7}
            |σ·by{.relevance}
            |α;

        // Generate response with context
        let response! = match context {
            Some(past) => self.generate_with_context(message, past),
            None => self.generate_fresh(message),
        };

        // Store interaction for future reference
        self.engram.store_episode(Episode {
            input: message,
            output: response.clone(),
            timestamp: Time::now(),
        });

        response
    }
}

Multi-Agent System

Multiple agents collaborating on a research task:

agent Researcher {
    execution: Daemon { tools: [Tool::WebSearch, Tool::FileSystem] },
    communication: Commune,
}

agent Analyst {
    memory: Engram { semantic: true },
    planning: Omen,
    communication: Commune,
}

agent Writer {
    subjectivity: Anima { personality: "clear, concise" },
    communication: Commune,
}

async fn research_project(topic: Str~) -> Report! {
    // Create agent swarm
    let researcher = Researcher::new();
    let analyst = Analyst::new();
    let writer = Writer::new();

    // Research phase
    researcher ! Message::Task { action: "research", topic };
    let findings~ = researcher ? Message::Result;

    // Analysis phase
    analyst ! Message::Task { action: "analyze", data: findings };
    let analysis~ = analyst ? Message::Result;

    // Writing phase
    writer ! Message::Task { action: "write", content: analysis };
    let draft~ = writer ? Message::Result;

    // Validate final output
    let report! = draft |validate!{
        .word_count() >= 500 &&
        .citations.len() > 0 &&
        .has_conclusion()
    };

    report
}