ADDRESS: The Escape Hatch to Other Domains
ADDRESS: The Escape Hatch to Other Domains
The ADDRESS statement is REXX’s fundamental mechanism for breaking out of the REXX language itself and delegating work to specialized external systems—what we call an “escape hatch to another domain.”
This concept is central to REXX’s philosophy: REXX orchestrates; other systems specialize.
What is an Escape Hatch?
Think of REXX as a control center and ADDRESS as an exit tunnel:
┌─────────────────────────────────────────┐
│ REXX Script (Orchestration) │
│ │
│ LET data = READ_FILE("input.txt") │
│ ADDRESS sql │◄──────┐
│ "SELECT * FROM table WHERE id IN..." │ │
│ LET result = /* SQL result */ │ │ Escape Hatch:
│ │ │ Leave REXX,
│ ADDRESS docker │◄──────┤ Enter SQL Domain
│ "run image=myapp command=process" │ │ (run command)
│ ADDRESS │ │ Return to REXX
│ SAY "Done: " || result │ │ (back to host)
└─────────────────────────────────────────┘ │
│
┌──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ SQL Database Engine │
│ (Specialized Domain) │
│ - Understands SQL syntax │
│ - Manages data/queries │
│ - Returns result sets │
└──────────────────────────────┘
Without ADDRESS, you’d need:
- A full SQL parser in REXX (duplication)
- Re-implementation of Docker CLI (reinvention)
- Bindings to 50 different APIs (bloat)
With ADDRESS, you escape to the specialized system and return with results.
The Core Insight: Delegation, Not Reimplementation
Classic languages force you to implement everything—or nothing:
- C: Write everything in C
- Python: Use Python libraries or external commands (awkward)
- JavaScript: Bound to browser/Node.js environment
REXX with ADDRESS inverts this:
- Write orchestration logic in REXX
- Escape to specialized domains for domain-specific work
- Bring results back to REXX for coordination
Example: A Simple Data Pipeline
-- Orchestration layer (REXX)
LET data = FILE_READ "raw_data.csv"
-- Escape to data processing domain
ADDRESS python
EXECUTE script=`
import pandas as pd
df = pd.read_csv('data.csv')
print(df.describe())
`
-- Back in REXX to coordinate results
LET summary = /* Python output */
ADDRESS email
sendReport to="analytics@company.com" body=summary
-- Continue coordinating
SAY "Pipeline complete"
No need to:
- Rewrite pandas in REXX
- Rewrite SMTP in REXX
- Rewrite file I/O for Python
Each domain handles its specialty; REXX coordinates the flow.
Historical Perspective: From Amiga to Cloud
The ARexx Era (1985–2010s)
ADDRESS originated in ARexx (Amiga Rexx), developed by William S. Hawes. It solved a real problem in the Amiga ecosystem: how to glue together diverse applications.
Amiga applications exposed scripting ports—essentially addressable interfaces. ARexx scripts could:
-- DPaint: Graphics Domain
ADDRESS DPAINT
FILL X=100 Y=50 COLOR=3
BRUSH "mybrush.brush"
DRAW LINE FROM 0 0 TO 320 200
-- Back in ARexx
SAY "Graphics command sent"
-- Directory Opus: File Management Domain
ADDRESS DOPUS
COPY SOURCE="Projects/*" DEST="Archive/"
MAKEDIR "Archive/2024"
-- PageStream: Desktop Publishing Domain
ADDRESS PAGESTREAM
IMPORT "document.txt"
FONT "Helvetica" SIZE=12
PARAGRAPH ALIGN=CENTER
Key insight: The same REXX syntax—ADDRESS target + command—worked across completely different applications. The ADDRESS handler was the “escape hatch” specific to each domain.
Why This Was Powerful
- Unified Scripting: One language (REXX) could orchestrate multiple applications
- Loose Coupling: Applications didn’t need to know about each other
- Extensibility: New applications could expose ADDRESS handlers; scripts automatically worked with them
- User Empowerment: Non-programmers could script with simple, readable syntax
Modern Parallels
Today’s ADDRESS handlers follow the same pattern:
-- Cloud Services Domain (Google Cloud Platform)
ADDRESS gcp
"SHEET 1BxiMVs0... SELECT * FROM 'Orders' WHERE date = TODAY()"
"BIGQUERY INSERT INTO analytics.daily_orders SELECT * FROM SHEETS_RESULT"
"FIRESTORE SET /metrics/today {\"orders\": 342, \"revenue\": 125000}"
"PUBSUB PUBLISH daily-metrics MESSAGE 'Dashboard updated'"
-- Containerization Domain (Docker)
ADDRESS docker
"create image=node:18 name=app-container"
"exec container=app-container command='npm install'"
-- AI/LLM Domain (Anthropic Claude)
ADDRESS claude
"messages role=user text='Analyze this dataset'"
LET analysis = /* Claude's response */
-- Database Domain (SQLite)
ADDRESS sqlite
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
"INSERT INTO users (name) VALUES ('Alice')"
The pattern is identical to ARexx:
- Switch to a domain via ADDRESS
- Send domain-specific commands
- Return results to REXX
- Coordinate next steps
ADDRESS as a Protocol Bridge
ADDRESS is fundamentally a protocol bridge: it translates between REXX’s imperative syntax and a domain’s native language/API.
REXX Code ADDRESS Handler Target System
────────────────── ─────────────────── ─────────────
ADDRESS docker ┌─ Parse command
"run image=node" ───►│ ┌─ Translate to Docker CLI Docker Engine
│ │ "docker run image=node" │
│ └─ Execute │
└─ Return result ◄────┘
ADDRESS sql ┌─ Parse command
"SELECT * FROM t" ───►│ ┌─ Build SQL AST SQL Engine
│ │ "SELECT * FROM t" │
│ └─ Execute │
└─ Return result set ◄────┘
The ADDRESS handler is the translator that:
- Parses the REXX command or function call
- Translates to the target system’s native format
- Executes in the target system
- Returns results to REXX
Four Types of Escape Hatches
1. Command-Based Escape
The handler receives raw commands and routes them to an interpreter:
ADDRESS shell
"ls -la /home" -- Sent as-is to shell interpreter
"docker ps | grep running" -- Sent as-is to shell interpreter
Use cases: OS shell, SQL engines, code interpreters
2. Function-Based Escape
The handler receives function calls with named/positional parameters:
ADDRESS calculator
clear -- Escape: call clear()
press button="5" -- Escape: call press("5")
LET result = getDisplay -- Escape: call getDisplay(), return result
Use cases: Application APIs, library functions, object methods
3. Heredoc-Based Escape
The handler receives multiline content blocks—useful for structured input:
ADDRESS sqlite <<SQL
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
SQL
ADDRESS python <<PYTHON_SCRIPT
import math
result = math.sqrt(144)
PYTHON_SCRIPT
Use cases: SQL/Python/JSON/XML generation, configuration DSLs, code generation
4. Pattern-Based Escape
The handler receives lines matching a regex pattern, enabling natural DSLs:
ADDRESS expectations MATCHING("^[ \t]*\. (.*)$")
. result should equal 42
. name should match "^[A-Z]"
Use cases: Test frameworks, logging, domain-specific assertions
The REXX Orchestration Model
ADDRESS enables a specific architectural pattern: REXX as the orchestration layer.
┌────────────────────────────────────────────────────┐
│ REXX Orchestration Script │
│ ──────────────────────────────────────────── │
│ • Control flow (IF/ELSE, DO loops) │
│ • Data transformation (string/array functions) │
│ • Decision logic (which domain to invoke next?) │
│ • Error handling (try/catch across domains) │
└────────┬──────────────┬──────────────┬─────────────┘
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ Domain │ │ Domain │ │ Domain │
│ 1 │ │ 2 │ │ 3 │
│ │ │ │ │ │
│ SQL │ │ Docker │ │ Cloud │
│Database│ │ Engine │ │ API │
└────────┘ └────────┘ └────────┘
This inversion of control has benefits:
| Traditional | REXX + ADDRESS |
|---|---|
| Script language bound to one domain | Script language coordinates many domains |
| Must hardcode domain logic | Domain logic in specialized systems (updated independently) |
| Tight coupling (language knows all APIs) | Loose coupling (language knows only syntax/protocol) |
| Difficult to test (domain code intertwined with logic) | Easier to test (mock domains by providing alternative handlers) |
| Hard to evolve (touching orchestration breaks domain code) | Easier to evolve (swap handlers without changing orchestration) |
Where Address Handlers Live
An ADDRESS handler is simply:
- A JavaScript function (in the RexxJS implementation) that receives commands/method calls
- A registry entry exposing it to REXX scripts
- A protocol defining how it translates REXX syntax to its target domain
Built-in Handlers (Core)
sqlite– SQLite database operationssystem/shell– OS command executionecho– Echo/testingexpectations– Test assertions
Extensible Handlers (Extras)
- Cloud:
gcp(Google Cloud),aws(Lambda),anthropic(Claude),openai(GPT) - Containers:
docker,podman,systemd-nspawn - VMs:
qemu,virtualbox,proxmox,firecracker,lxd - Data:
duckdb,pyodide(Python in browser) - APIs: Custom handlers for any REST/RPC service
User-Defined Handlers
You can register your own:
// my-handler.js
function MY_HANDLER_ADDRESS_META() {
return {
canonical: "my.org/my-handler",
provides: { addressTarget: "myapp" }
};
}
async function ADDRESS_MY_HANDLER(method, params) {
// Handle REXX calls to ADDRESS myapp
return { success: true, result: /* ... */ };
}
// Then in REXX:
// ADDRESS myapp
// doSomething arg1=value1
From Concept to Practice
A Complete Example: Photo Processing Pipeline
-- REXX orchestration layer
REQUIRE "gcp-address"
REQUIRE "claude-address"
-- Read list of image files
LET imageList = FILE_READ "images-to-process.txt"
LET images = SPLIT text=imageList delimiter="\\n"
-- Process each image
DO i = 1 TO LENGTH images
LET imagePath = ARRAY_GET array=images index=i
-- Escape to GCP: Upload to Cloud Storage
ADDRESS gcp
"upload path={imagePath} to gs://my-bucket/raw/"
-- Escape to GCP: Trigger image analysis via Cloud Vision
"vision analyze image=gs://my-bucket/raw/{imagePath}"
LET visionResult = /* GCP response */
-- Escape to Claude: Interpret results
ADDRESS claude
LET interpretation = "messages role=user text='Analyze this image data: {visionResult}'"
-- Back in REXX: Coordinate results
LET report = "Image: {imagePath}, Vision: {visionResult}, Interpretation: {interpretation}"
-- Escape to database: Store analysis
ADDRESS sqlite
"INSERT INTO image_analysis (path, vision_data, interpretation) VALUES (?, ?, ?)"
SAY "Processed: " || imagePath
END
-- Final coordination: Generate summary report
ADDRESS gcp
"firestore set /reports/daily path={reportPath}"
SAY "Pipeline complete!"
This script:
- Orchestrates in REXX (loops, conditionals, data flow)
- Escapes to GCP for cloud operations
- Escapes to Claude for AI analysis
- Escapes to SQLite for storage
- Returns with results at each step
No REXX script reimplements cloud services, AI models, or database engines. Each domain stays specialized; REXX stays focused on orchestration.
Key Principles
- ADDRESS is NOT a library system – it’s a context switch mechanism
- A library (
REQUIRE) loads code into your REXX environment - An ADDRESS target (
ADDRESS name) delegates to an external system
- A library (
- ADDRESS is NOT just for APIs – it’s for any external domain
- Shell commands (OS domain)
- SQL queries (database domain)
- Docker commands (container domain)
- Python code (interpreter domain)
- ADDRESS is NOT limited to strings – modern RexxJS supports function calls with named parameters
function param1=value param2=value- Results can be complex objects, not just strings
- ADDRESS is composable – you can chain ADDRESS calls to build complex workflows
- REXX glues everything together
- Each ADDRESS handler is independently testable
Migration from ARexx
If you’re coming from ARexx scripting:
| ARexx | RexxJS |
|---|---|
ADDRESS DPAINT → paint commands |
ADDRESS canvas → canvas operations |
ADDRESS DOPUS → file operations |
ADDRESS docker → container operations |
ADDRESS PAGESTREAM → document layout |
ADDRESS cloudStorage → cloud operations |
| Amiga ports (binary protocols) | Web handlers (JSON/RPC protocols) |
| System-specific persistence | Cloud-based persistence |
The conceptual model is identical: use ADDRESS to escape REXX and operate in another domain. The target domains have evolved from Amiga applications to cloud services, databases, and AI systems.
See Also
- Application Addressing – Technical reference for ADDRESS syntax
- ADDRESS Handlers Reference – Complete list of available handlers
- History and Patterns – Deep dive into ADDRESS evolution
- HEREDOC Patterns – Multi-line content handling
- MATCHING Patterns – Regex-based routing
Core Takeaway: ADDRESS is REXX’s answer to the question “How do I use something outside REXX?” The answer: escape hatch. Leave REXX when you need a specialist; bring results back when done. Coordinate everything in REXX.