Enforcing 1‑Based Indexing in Dyalog APL with ⎕IO: A Practical Guide
Learn how to set and lock the array index origin to 1 in Dyalog APL, preventing off‑by‑one errors across scripts and libraries. Follow a step‑by‑step procedure, verify with tests, and recover if the origin changes.
01 Jul 2026, 04:00 UTC

Set the Desired Outcome
When a team shares code that mixes legacy scripts, third‑party libraries, and data imported from external sources, a common source of bugs is the assumption about array index origin. Dyalog APL defaults to 0‑based indexing in many dialects, but many developers prefer 1‑based indexing for readability and to match mathematical notation. The goal of this guide is to enforce a deterministic 1‑based origin across a project so that every ⎕IO value is 1, preventing off‑by‑one errors.
Prerequisites
- A running Dyalog APL session (any version from 17.x onward).
- Write access to the workspace or the script header where
⎕IOis set. - Team agreement on a single origin convention for the codebase.
- Knowledge of basic Dyalog APL syntax (variables, functions, and the
⎕IOsystem variable).
Procedure
- Set the Origin Early
Insert the following line as the first executable statement in your main script or in a common initialization file that is sourced by every worker process:
⎕IO←1This command must run before any arrays are created or indexed.
⎕IOis a global system variable, so setting it here applies to the entire session. - Persist the Setting
If you use a workspace file (.dyalog) or a project‑wide initialization script, include the
⎕IO←1line there. This guarantees that every new session starts with the same origin. - Wrap Reusable Functions
To guard against accidental changes by imported code, add a quick check at the beginning of any function that relies on 1‑based indexing:
⍝ Example: a function that extracts a slice Slice←{⎕IO≠1:⎕←'Error: Origin changed';⍬ ⋄ 2↑⍵}Here
⎕IO≠1evaluates to1if the origin is not 1, causing the function to abort early. - Isolate Code with Different Origin Needs
If a third‑party library requires 0‑based indexing, run it in a separate session or save and restore
⎕IOaround the call:orig←⎕IO ⎕IO←0 ⍝ Call library that expects 0‑based origin result←SomeLibraryFunction data ⎕IO←orig ⍝ Restore
Expected Checks
- After initialization, run
⎕IOand confirm it returns1. - Test a known index expression:
2⊃'ABC'should return'B'under 1‑based origin. - Verify that
take/dropoperations behave consistently. For example,3↑'ABCDE'should return'ABC'. - Run unit tests that include an assertion:
⎕IO=1is true.
Recovery Options
If a library or a piece of code changes ⎕IO unexpectedly, you can restore the desired origin with a single command:
⎕IO←1
For diagnostic purposes, you can capture the current origin before calling external code and restore it afterward, as shown in the Isolate Code step above.
Limitations and Caveats
- Global Scope:
⎕IOis session‑wide. Changing it affects all subsequent array operations, which can break third‑party libraries that assume a different origin. - Dialect Variations: GNU APL and older APL systems may handle
⎕IOdifferently. Explicit checks are required for cross‑dialect portability. - Array Creation Timing: Setting
⎕IOafter arrays have been created does not retroactively change their indexing semantics; only future operations are affected.
Practical Verification
After following the steps, run the following in the console to confirm everything is in order:
⎕IO←1 ⍝ Ensure origin is 1
⎕IO ⍝ Expect 1
2⊃'ABC'⍝ Expect 'B'
3↑'ABCDE'⍝ Expect 'ABC'
If any of these expressions return unexpected results, review the order of ⎕IO←1 placement and any imported code that might alter the origin.
Conclusion
By setting ⎕IO←1 early, persisting the setting, and guarding reusable functions with origin checks, teams can maintain a consistent 1‑based indexing convention across all scripts and libraries. This reduces off‑by‑one bugs, improves readability, and ensures that your Dyalog APL code behaves predictably regardless of external dependencies.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.