TBT (1/?): My First Program Was a Horse Race
1138 words • 6 min read • Abstract

My first program was a horse race. Written in APL. On a mainframe. In 1972.
This is the first Throwback Thursday post—a series where I revisit the technologies, languages, and ideas that shaped how I think about programming.
| Resource | Link |
|---|---|
| Code | apl-horse-race |
| Demo | Live Demo |
| GNU APL | gnu.org/software/apl |
| Video | Greek Code, No Lowercase #TBT![]() |
APL: A Programming Language
APL was created by Kenneth Iverson at IBM in the 1960s. The name literally means “A Programming Language”—Iverson was a mathematician who designed it as a notation for describing algorithms before it became an actual programming language.
What made APL special:
| Feature | Description |
|---|---|
| Array-oriented | Operations work on entire arrays, not single values |
| Symbolic notation | Greek letters and mathematical symbols as operators |
| Interactive | REPL-style development decades before it was common |
| Terse | Complex operations in a few characters |
APL programs look like nothing else:
POS←POS+?5⍴3
This single line adds random values (1-3) to all five horse positions simultaneously. No loops. No iteration. The operation just happens across the entire array.
The IBM 2741 Experience
In 1972, APL\360 ran on IBM mainframes. You accessed it through terminals like the IBM 2741—essentially a modified Selectric typewriter with a special APL typeball.
The typeball had all the APL glyphs: ⍴ ⍳ ∇ ⎕ ← ⌈ ⌊ ⍵ ⍺ ∘ ⊃ ⊂ and dozens more. You physically typed these symbols. The keyboard layout was completely different from anything you’d seen before.
When you made an error, there was no backspace in the modern sense. You’d overstrike characters or start the line over. Programs were stored in workspaces, saved to tape or disk.
The terminal printed on paper. Every interaction left a physical record.
The Horse Race Program
Horse race simulations were popular APL demonstrations. They showed off several things:
- Random number generation (
?roll operator) - Array operations (updating all positions at once)
- Character graphics (crude but effective visualization)
- Interactive output (watching the race unfold)
Here’s the verbose version from the repo:
∇ RACE;HORSES;POS;FINISH;ROUND;_
HORSES←'LUCKY ' 'THUNDER' 'SHADOW ' 'COMET ' 'BLAZE '
POS←5⍴0
FINISH←15
ROUND←0
⎕←'══════════════════════════════════════════'
⎕←' THE RACE IS ON!'
⎕←'══════════════════════════════════════════'
LOOP:ROUND←ROUND+1
⎕←'--- ROUND ',(⍕ROUND),' ---'
POS←POS+?5⍴3
SHOWHORSES
→DONE×⍳∨/POS≥FINISH
→LOOP
DONE:⎕←'WINNER: ',((⊃(POS=⌈/POS)/⍳5)⊃HORSES),'!'
∇
Key APL Idioms
Array creation:
POS←5⍴0 ⍝ Create array of 5 zeros
The ⍴ (rho) operator reshapes. 5⍴0 means “reshape 0 into a 5-element array.”
Random numbers:
?5⍴3 ⍝ Roll 5 dice, each 1-3
The ? operator is “roll”—like rolling dice. ?5⍴3 rolls five 3-sided dice.
Finding the winner:
(⊃(POS=⌈/POS)/⍳5)⊃HORSES
This reads right-to-left:
⌈/POS— maximum of all positionsPOS=⌈/POS— boolean mask: which horses are at max?/⍳5— compress: keep only those indices⊃— take the first one⊃HORSES— select that horse’s name
One line. No loops. Pure array thinking.
The Idiomatic Version
APL programmers pride themselves on terseness. The idiomatic version does the same thing in fewer characters:
HORSES←'LUCKY ' 'THUNDER' 'SHADOW ' 'COMET ' 'BLAZE '
∇ SHOW;I
I←1
N:⎕←(I⊃HORSES),'│',((I⊃POS)⍴'░'),'▓'
I←I+1
→N×⍳I≤5
∇
∇ RACE;POS;_
POS←5⍴0
⎕←'THE RACE IS ON!'
L:_←⎕DL 0.3
POS←POS+?5⍴3
SHOW
⎕←''
→L×⍳~∨/POS≥15
⎕←'WINNER: ',(⊃(POS=⌈/POS)/⍳5)⊃HORSES
∇
The entire program fits on a single screen. This was the APL aesthetic: powerful ideas expressed concisely.
Running It Today
GNU APL implements ISO 13751 (Extended APL) and runs on modern systems:
# macOS
brew install gnu-apl
# Arch Linux
yay -S gnu-apl
# Run the race
git clone https://github.com/sw-comp-history/apl-horse-race
cd apl-horse-race
apl -f src/race.apl
Sample output:
══════════════════════════════════════════
THE RACE IS ON!
══════════════════════════════════════════
--- ROUND 1 ---
LUCKY │▓▓▓◄
THUNDER │▓▓◄
SHADOW │▓◄
COMET │▓▓▓◄
BLAZE │▓▓◄
The horses advance randomly until one crosses the finish line.
What APL Taught Me
APL shaped how I think about programming in ways that persist today:
1. Think in arrays, not loops.
When I see a problem, I ask: can this be expressed as an operation on a whole collection? Languages like NumPy, R, and Julia carry this forward.
2. Notation matters.
Good notation can make complex ideas simple. Bad notation obscures them. APL’s symbols were controversial, but they made array operations visible in ways that verbose syntax doesn’t.
3. The REPL is powerful.
Interactive development—type an expression, see the result immediately—was central to APL decades before it became fashionable again with Jupyter notebooks and modern REPLs.
4. Terseness has value.
Not obfuscation for its own sake, but the ability to see an entire algorithm at once. When your program fits on one screen, you can reason about the whole thing.
APL’s Legacy
APL influenced many languages:
| Language | Year | APL Influence |
|---|---|---|
| J | 1990 | Iverson’s ASCII-only redesign |
| K/Q | 1993 | Powers financial systems at Kx |
| A+ | 1988 | Morgan Stanley’s open-source APL |
| BQN | 2020 | Modern APL with cleaner semantics |
| NumPy | 2006 | Array operations in Python |
| R | 1993 | Vector operations for statistics |
The ideas live on, even if the glyphs don’t.
Implementation Details
| Metric | Value |
|---|---|
| Primary Language | APL |
| Source Files | 2 .apl files |
| Lines of Code | ~50 lines total |
| Runtime | GNU APL |
| Also Includes | Documentation, PNG samples for Unicode issues |
Good for you if: You want to understand array programming origins, learn basic APL, or experience what programming felt like in the 1970s.
Complexity: Low. The program is intentionally simple—a teaching example, not production code. The repo includes extensive documentation explaining every line.
Why Throwback Thursday?
Programming didn’t start with Python and JavaScript. Every abstraction we use today was invented by someone solving a real problem.
TBT posts will explore:
- Languages that shaped my thinking (APL, Lisp, Forth)
- Technologies that were ahead of their time (CMS/TSO Pipelines, dataflow)
- Ideas worth revisiting with modern tools
Understanding where we came from helps us see where we’re going.
Resources
- apl-horse-race Repository
- GNU APL
- APL Wiki
- Iverson’s Turing Award Lecture: “Notation as a Tool of Thought”
- Video: Greek Code, No Lowercase #TBT
Have your own “first program” story? Find me on YouTube @SoftwareWrighter.
Part 1 of the Throwback Thursday series. View all parts | Next: Part 2 →
