Self-Documenting Scripts

Lambda Smalltalk's syntax reads like English. Your scripts become their own documentation.

The Problem with Traditional Scripts

Shell script:

#!/bin/bash
for h in $(cat hosts.txt); do
  ssh $h "systemctl restart nginx" && \
  curl -s -o /dev/null -w "%{http_code}" http://$h/health | grep -q 200 && \
  echo "$h: OK" || echo "$h: FAILED"
done

What does this do? You need to parse the syntax mentally.

Python:

for host in open('hosts.txt'):
    subprocess.run(['ssh', host.strip(), 'systemctl restart nginx'])
    r = requests.get(f'http://{host.strip()}/health')
    print(f"{host.strip()}: {'OK' if r.status_code == 200 else 'FAILED'}")

Better, but still requires programming knowledge to read.

The Smalltalk Way

"Restart nginx on all servers and verify health"

hosts := (File read: 'hosts.txt') lines.

hosts do: [:host |
    host restart: 'nginx'.

    (host healthCheck)
        ifTrue:  [ (host, ': OK') printNl ]
        ifFalse: [ (host, ': FAILED') printNl ].
].

Read it aloud:

The code is the documentation.

Note: The examples on this page are conceptual. Selectors such as host restart:, Database dump:to:, S3 upload:, Slack notify:, and Git pull: illustrate the readable, intent-revealing style you can build — they are not built-in classes. The actual building blocks are listed under Getting Started below, with the full set in the API Reference.


Why This Matters

1. Auditable Operations

When regulators ask "what does this script do?", you can show them the code directly:

"Daily backup procedure"

Database dump: 'production' to: '/backup/daily/'.
S3 upload: '/backup/daily/' to: 'company-backups' prefix: (Date today asString).
Slack notify: '#ops' message: 'Daily backup completed'.

No separate runbook needed. The script is the runbook.

2. Reduced Bus Factor

New team members can read and understand operations scripts immediately:

"Deploy to staging"

Git pull: 'origin/main'.
Docker build: '.' tag: 'app:staging'.
Kubernetes apply: 'k8s/staging.yaml'.

(App healthCheck: 'staging')
    ifTrue:  [ Slack notify: 'Staging deploy successful' ]
    ifFalse: [ Slack notify: 'Staging deploy FAILED' ].

No tribal knowledge required.

3. Fewer Mistakes

When the intent is clear, mistakes are obvious:

"Archive old logs (WRONG - deletes instead of archiving!)"
Logs olderThan: 30 days delete.

"Archive old logs (CORRECT)"
Logs olderThan: 30 days moveTo: '/archive/'.

The bug is visible to anyone who reads the code.


Real-World Patterns

Health Monitoring

"Check all services every 5 minutes"

services := #('web-01' 'web-02' 'db-primary' 'cache-01').

services do: [:svc |
    (svc isHealthy) ifFalse: [
        PagerDuty alert: svc , ' is DOWN'.
        svc restart.

        (svc isHealthy)
            ifTrue:  [ PagerDuty resolve: svc , ' recovered after restart' ]
            ifFalse: [ PagerDuty escalate: svc , ' still DOWN after restart' ].
    ].
].

Data Pipeline

"ETL: Extract from source, transform, load to warehouse"

data := Postgres query: 'SELECT * FROM events WHERE date = today()'.

data := data
    select: [:row | row at: 'status' = 'completed']
    collect: [:row | row transform: TransformRules].

BigQuery insert: data into: 'analytics.daily_events'.

('Processed ', data size asString, ' records') printNl.

Deployment with Rollback

"Blue-green deployment with automatic rollback"

| previousVersion |
previousVersion := App currentVersion.

App deploy: newVersion to: 'green'.

(App healthCheck: 'green')
    ifTrue: [
        LoadBalancer switchTo: 'green'.
        Slack notify: 'Deployed ', newVersion, ' successfully'.
    ]
    ifFalse: [
        App rollbackTo: previousVersion.
        Slack notify: 'Deploy failed, rolled back to ', previousVersion.
        PagerDuty alert: 'Deployment failure'.
    ].

Getting Started

Lambda Smalltalk provides the building blocks. Combine them with:

See Examples for more patterns.