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:

  1. Specialization: You can’t implement SQL, Docker, Kubernetes, and AI in one language
  2. Consistency: REXX’s syntax is easier to learn than 50 different APIs
  3. Composition: You can combine domains without modifying them
  4. Decoupling: Changes to a domain don’t break orchestration code
  5. 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


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.