ADDRESS: History and Evolution of Domain Escaping
ADDRESS: History and Evolution of Domain Escaping
A historical and technical exploration of how ADDRESS evolved from ARexx to modern RexxJS, showing the persistence of the “escape hatch” pattern across different eras and platforms.
Timeline: From Amiga to Cloud Computing
1. ARexx Era (1985–2010)
Context: The Amiga (1985+) was a revolutionary multitasking system. Disparate applications needed to communicate and be scripted together.
Solution: ARexx (Amiga Rexx) by William S. Hawes introduced rexx ports—standardized scripting interfaces that applications could expose. ADDRESS became the mechanism to access them.
Classic Amiga Application Domains
DPaint (Graphics Domain)
-- ARexx script for automated graphics processing
ADDRESS DPAINT
-- Escape to graphics editing domain
WINDOW FRONT -- Focus DPaint window
BRUSH "mystyle.brush" -- Select brush
FILL X=100 Y=50 COLOR=3 -- Fill operation
-- Domain-specific coordinate system and operations
DRAW FILLEDCIRCLE X=150 Y=150 RADIUS=50 COLOR=5
DRAW LINE FROM 0 0 TO 320 200 COLOR=1
FLOOD X=200 Y=200 COLOR=2 -- Bucket fill
-- Save in graphics domain's native format
SAVE "output.ilbm"
SAY "Graphics rendering complete"
Why ADDRESS was necessary: DPaint’s C code couldn’t be reimplemented in REXX, but REXX could be the orchestration layer.
Directory Opus (File Management Domain)
-- ARexx script for automated file management
ADDRESS DOPUS
-- Escape to file management domain
HIDE -- Hide inactive window
REFRESH -- Refresh directory
OPENDIR "Archive" -- Change directory to Archive
-- File operations in their native context
COPY SOURCE="Projects/*" DEST="Archive/2024"
MAKEDIR "Archive/2024-Backups"
PROTECT FILE="Archive/README" FLAGS="r" SET=1
DELETE "temp/*"
-- Domain-native queries
LET dirSize = FILESIZE "Archive"
SAY "Archive size: " || dirSize
REFRESH -- Update display
Pattern: Each command uses the file system domain’s perspective—paths, attributes, permissions as Directory Opus understands them.
PageStream (Desktop Publishing Domain)
-- ARexx script for document processing
ADDRESS PAGESTREAM
-- Escape to desktop publishing domain
LOAD "document.txt" -- Load document in PageStream format
FONT "Helvetica" SIZE=12
-- Text formatting commands (PageStream-specific)
PARAGRAPH ALIGN=CENTER INDENT=0.5
STYLE BOLD
TEXT "My Document Title"
PARAGRAPH ALIGN=LEFT INDENT=0.25
STYLE NORMAL
TEXT "This is body text in my document."
-- Pagination and layout
PAGE INSERT AFTER=1
TEXT "Page 2 content..."
-- Export in publishing format
EXPORT TYPE=PDF FILENAME="document.pdf"
Pattern: The script doesn’t need to understand typography or PDF generation—it delegates to the specialist system.
GoldEd (Text Editing Domain)
-- ARexx script for batch text editing
ADDRESS GOLDED
-- Escape to text editing domain
LOAD "source.txt"
GOTO LINE=10
-- Text manipulation commands
SELECT CHARS=5 -- Select 5 characters
DELETE -- Delete selection
INSERT "new text" -- Insert replacement
-- Search and replace (editor's domain)
FIND "old_pattern"
FINDREPLACE "old" "new" ALL
-- Save with editor-specific options
SAVE BACKUP=1 TIMESTAMP=1
Pattern: Regular expression search/replace in their native form, buffer management as the editor understands it.
2. The “Lost Decade” (2010–2020)
For ~10 years, ADDRESS fell out of favor:
- Desktop applications declined (moved to web)
- REST APIs emerged but weren’t standardized for scripting
- Java/Python dominated, with built-in library systems
- REXX fragmentation: Classic REXX, Object REXX, ooRexx splintered
However, the concept persisted in:
- Open Object Rexx (ooRexx) maintained ADDRESS mechanisms
- IBM i (legacy) continued REXX/ADDRESS for system scripting
- Specialized domains like databases continued using REXX with ADDRESS handlers
3. RexxJS Renaissance (2020s)
Context: JavaScript ecosystem, cloud APIs, and containerization created new domains that needed orchestration.
Solution: RexxJS reimagines ADDRESS for the modern era—not with system-level ports, but with web handlers for cloud services, APIs, and languages.
Modern RexxJS Address Handlers
Cloud Services Domain (Google Cloud)
-- RexxJS script for cloud orchestration
ADDRESS gcp
-- Escape to Google Cloud domain
"SHEET 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms SELECT * FROM 'Orders' WHERE date = TODAY()"
LET orders = /* GCP sheet query result */
-- Access BigQuery (analytics) domain within GCP
"BIGQUERY INSERT INTO analytics.daily_orders SELECT * FROM SHEETS_RESULT"
-- Access Firestore (NoSQL) domain within GCP
"FIRESTORE SET /metrics/today {\"orders\": ARRAY_LENGTH(orders), \"revenue\": CALCULATE_TOTAL(orders)}"
-- Publish to Pub/Sub (messaging) domain within GCP
"PUBSUB PUBLISH daily-metrics MESSAGE 'Dashboard updated'"
SAY "Cloud pipeline complete"
Pattern match with ARexx:
- Switch to domain (SHEET, BIGQUERY, FIRESTORE, PUBSUB)
- Use domain-specific commands
- Return results to REXX
- Continue orchestration
Container Domain (Docker)
-- RexxJS script for container orchestration
ADDRESS docker
-- Escape to container management domain
"create image=node:18 name=app-container"
"exec container=app-container command=\"npm install\""
"exec container=app-container command=\"npm test\""
-- Domain-native operations
"commit container=app-container repository=myapp version=1.0"
"push repository=myapp version=1.0"
ADDRESS docker
LET running = "ps | grep myapp"
SAY "Running containers: " || running
Pattern match with Directory Opus:
- Container management like file management
- Hierarchical entities (images, containers, volumes)
- Domain-specific operations (create, exec, commit)
Database Domain (SQLite)
-- RexxJS script for database operations
ADDRESS sqlite
-- Escape to SQL domain (matches ARexx "Escape to PageStream")
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)
-- SQL is its own language; ADDRESS HEREDOC lets us use it naturally
ADDRESS sqlite <<SQL
INSERT INTO users (name, email) VALUES
('Alice Johnson', 'alice@example.com'),
('Bob Smith', 'bob@example.com'),
('Carol Davis', 'carol@example.com')
SQL
-- Complex queries (domain expertise)
LET result = sqlite "SELECT u.*, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id"
SAY "Query returned " || ARRAY_LENGTH(result) || " rows"
Pattern match with GoldEd:
- SQL has its own language (like editor macros)
- Query results dominate the interaction
- Complex transformations stay in the domain
AI/LLM Domain (Anthropic Claude)
-- RexxJS script for AI analysis
ADDRESS claude
-- Escape to AI domain
LET analysis = "messages role=user text='Analyze this customer feedback: {customerText}'"
-- Domain returns structured response
IF INCLUDES analysis "sentiment=positive" THEN
ADDRESS email
sendNotification to="sales@company.com" subject="Positive feedback received"
ENDIF
SAY "Analysis: " || analysis
Pattern match with DPaint:
- High-level command (analyze)
- Domain returns domain-specific result (sentiment, topics, etc.)
- REXX continues orchestration with results
The Persistent Pattern: Domain Switching
Despite 40 years of technology evolution, the ADDRESS pattern remains constant:
ADDRESS <domain>
<domain-specific-command>
<return to REXX>
Domain Matrix: ARexx → RexxJS
| Dimension | ARexx Era | RexxJS Modern |
|---|---|---|
| Graphics | DPaint (bitmap editor) | Canvas APIs, WebGL |
| File Management | Directory Opus | Docker volumes, Cloud Storage, S3 |
| Document Processing | PageStream (typesetting) | Cloud Document APIs, PDF libraries |
| Text Editing | GoldEd (editor) | IDE APIs, Code transformation services |
| Communication | Manual port setup | REST/JSON-RPC (automatic) |
| Persistence | Local filesystem | Cloud databases (Firestore, DynamoDB) |
| Computation | Amiga CPU | Serverless (Lambda, Cloud Functions) |
| AI/ML | External tools | Built-in services (Claude, GPT, Gemini) |
| Transport | Binary ports | HTTP/WebSocket (web standard) |
Key insight: The role of ADDRESS remains constant (context switching), but target domains have evolved with technology.
Six Architectural Patterns
Pattern 1: Simple Command Dispatch
Concept: Send commands to a domain, get results back.
-- ARexx: File management
ADDRESS DOPUS
DELETE "tempfiles/*"
-- RexxJS: Container management
ADDRESS docker
"stop container=old-app"
Application: Stateless operations, one-shot actions.
Pattern 2: Stateful Session
Concept: Establish context in a domain, perform operations within that context.
-- ARexx: Editor context
ADDRESS GOLDED
LOAD "file.txt"
GOTO LINE=50
DELETE LINES=10
SAVE
-- RexxJS: Database context
ADDRESS sqlite
"CREATE TABLE users (id INTEGER, name TEXT)"
"INSERT INTO users VALUES (1, 'Alice')"
LET count = "SELECT COUNT(*) FROM users"
Application: Multi-step processes, maintaining domain state.
Pattern 3: Query and Decision
Concept: Query a domain, make decisions in REXX based on results.
-- ARexx: Check file status
ADDRESS DOPUS
LET fileSize = FILESIZE "bigfile.bin"
IF fileSize > 1000000 THEN DO
SAY "File too large"
-- Handle in REXX
END
-- RexxJS: Check cloud status
ADDRESS gcp
LET instances = "compute list instances"
DO i = 1 TO LENGTH(instances)
LET instance = ARRAY_GET instances i
IF instance.status = "STOPPED" THEN
ADDRESS gcp "compute start instance=" || instance.name
ENDIF
END
Application: Conditional workflows, adaptive orchestration.
Pattern 4: Pipeline Chaining
Concept: Connect multiple domains in sequence.
-- ARexx: Read from directory, process in editor, display result
ADDRESS DOPUS
LET files = FILESPEC "F" "*.txt" -- Get file list from file manager
DO i = 1 TO LENGTH(files)
ADDRESS GOLDED
LOAD files.i
LET content = READALL -- Read content
-- Process in REXX
LET processed = UPPER content
-- Write back via file manager
ADDRESS DOPUS
SAVE file=processed
END
-- RexxJS: Read from cloud, transform, write to database
ADDRESS gcp
LET cloudData = "storage read file=gs://bucket/data.json"
-- Transform in REXX (or another ADDRESS target)
LET transformed = JSON_PARSE cloudData
-- Write to database
ADDRESS sqlite
"INSERT INTO results VALUES (?)"
Application: ETL (Extract-Transform-Load) workflows.
Pattern 5: Error Handling and Fallback
Concept: Try a domain, fall back to alternative if it fails.
-- ARexx: Try primary storage, fall back to backup
TRY
ADDRESS PRIMARY_DISK
SAVE "file.txt"
CATCH
SAY "Primary storage failed, trying backup"
ADDRESS BACKUP_DISK
SAVE "file.txt"
END
-- RexxJS: Try cloud API, fall back to local
TRY
ADDRESS gcp
LET data = "storage read file=gs://bucket/data.json"
CATCH
SAY "Cloud failed, using local fallback"
LET data = FILE_READ "local-cache/data.json"
END
Application: Resilient systems, graceful degradation.
Pattern 6: Parallel Operations (Conceptual)
Concept: Dispatch to multiple domains concurrently.
-- RexxJS: Parallel cloud operations (simulated in RexxJS)
-- Send async requests to multiple domains
ADDRESS gcp
"storage upload file=data1.json" ASYNC=true
ADDRESS aws
"s3 put object=data1.json bucket=backup-bucket" ASYNC=true
-- Check status/results when ready
LET gcpDone = "storage get-operation-status ..."
LET awsDone = "s3 get-operation-status ..."
-- Continue when both complete
IF gcpDone AND awsDone THEN
SAY "Backup complete"
ENDIF
Application: Distributed operations, parallel processing.
Why ADDRESS Endures
Despite six decades of programming language evolution, ADDRESS persists because it solves a fundamental problem:
- Specialization: You can’t implement SQL, Docker, Kubernetes, and AI in one language
- Consistency: REXX’s syntax is easier to learn than 50 different APIs
- Composition: You can combine domains without modifying them
- Decoupling: Changes to a domain don’t break orchestration code
- Reusability: A REXX script can evolve as domains upgrade independently
Modern Challenges and Solutions
Challenge 1: API Explosion
ARexx: ~20-30 applications with rexx ports available RexxJS: Thousands of REST APIs, cloud services, libraries
Solution: RexxJS ADDRESS handlers are protocol adapters:
- Abstract REST/JSON-RPC details
- Provide domain-specific syntax
- Handle authentication transparently
Challenge 2: Asynchronous Operations
ARexx: Mostly synchronous (wait for command to complete) RexxJS: Many operations are async (cloud jobs, background tasks)
Solution: CHECKPOINT-based progress reporting and async-aware handlers:
ADDRESS cloudJob
LET jobId = submitLongRunningJob data=input
SAY "Job ID: " || jobId
-- Check periodically
DO i = 1 TO 100
LET status = checkJobStatus jobId=jobId
IF status.complete THEN
LET result = status.result
EXIT
ENDIF
WAIT milliseconds=1000
END
Challenge 3: Complex Authentication
ARexx: Local ports (same system) RexxJS: Remote APIs (internet-based)
Solution: Handlers manage authentication:
-- Handler auto-includes API keys from environment
ADDRESS gcp
-- Handler reads GCP_CREDENTIALS automatically
"bigquery query sql='SELECT * FROM dataset.table'"
Challenge 4: Type Safety
ARexx: Loose (strings, mostly) RexxJS: More structured (JSON, objects, arrays)
Solution: Parameter converters in handlers:
-- REXX (flexible)
ADDRESS sqlite
LET result = "SELECT * WHERE id = 123"
-- Handler converts to proper SQL:types, sanitizes, executes
Lessons from the Timeline
Lesson 1: Core Concepts Are Timeless
The ADDRESS escape-hatch concept solved problems in 1985 (automating graphics programs) and still solves them in 2025 (orchestrating cloud services). The domains changed, not the pattern.
Lesson 2: Domain Boundaries Matter
Whether it’s DPaint (graphics) or Claude (AI), ADDRESS works because it respects domain boundaries:
- REXX orchestrates and coordinates
- Each domain stays focused on its specialty
- Handoff is clean and unambiguous
Lesson 3: Loose Coupling Wins
ARexx scripts could work with new applications (added later) without modification because ADDRESS is decoupled from specific applications. RexxJS scripts can work with new cloud services the same way.
Lesson 4: Syntax Stability Matters
REXX’s ADDRESS syntax hasn’t fundamentally changed in 40 years:
ADDRESS target "command"
ADDRESS target function param=value
This stability means old patterns transfer to new domains.
Practical Migration: ARexx to RexxJS
If you’re translating ARexx scripts to RexxJS:
1. Identify Domains
-- ARexx
ADDRESS DOPUS → Identify: File management domain
ADDRESS DPAINT → Identify: Graphics domain
ADDRESS PAGESTREAM → Identify: Document processing domain
2. Find Modern Equivalent
DOPUS → docker (container management) or gcp storage
DPAINT → canvas APIs or WebGL handlers
PAGESTREAM → cloud document APIs or PDF generators
3. Adapt Syntax
-- ARexx: Amiga-specific commands
ADDRESS DOPUS
MAKEDIR "folder"
FILESIZE "file.txt"
-- RexxJS: Docker equivalents
ADDRESS docker
"create directory=/app/folder"
LET size = "exec container=c command='stat -c %s file.txt'"
4. Handle Async
-- ARexx: Synchronous (everything waits)
ADDRESS SYSTEM
"long_command" -- Blocks until done
-- RexxJS: Async-aware
ADDRESS cloudJob
LET jobId = "submitJob command=long_command"
-- Doesn't block; check status periodically
See Also
- Address: The Escape Hatch – Conceptual overview
- Application Addressing – Technical reference
- ADDRESS Handlers Reference – Full handler implementations
- REXX Language Reference – REXX language fundamentals
Core Takeaway: ADDRESS is a 40-year-old solution to a timeless problem: “How do I use a specialized domain from a general-purpose orchestration language?” Whether automating DPaint in 1985 or orchestrating Kubernetes in 2025, the answer remains: ADDRESS to escape, do work, return with results.