m←3 3⍴⍳9
m×1010 20 30 40 50 60 70 80 90
apl magicsaplnb
aplnb adds %apl and %%apl magics to Jupyter and IPython, which execute code in Dyalog APL. It talks to the interpreter over the RIDE protocol, the same protocol Dyalog’s own IDE uses, so nothing needs to be loaded into your workspace, output looks exactly like a Dyalog session, and errors are detected reliably. See core for a step by step walkthrough of the protocol and of how aplnb is built on it.
First, install Dyalog APL. Dyalog provides a basic license for free. aplnb is developed against Dyalog 20.0; 18.2 and later may work but are untested. Once Dyalog is installed, install aplnb with:
pip install aplnb
Once that’s complete, you can install the magics to all IPython and Jupyter sessions automatically by running in your terminal:
aplnb_install
The Dyalog interpreter itself only starts the first time you run an apl magic, so having aplnb installed everywhere costs nothing when you don’t use it.
After first running an apl magic in a notebook, the APL language bar by Adám Brudzewsky is automatically added to the current page. (aplnb bundles a modified copy of Adám’s lb.js; the file header lists the changes. The most visible ones: type a backtick twice in a row to enter triple backticks, get a ⋄ glyph with backtick-q, and use the ▲/▼ button beside the close button to choose whether the bar pushes the page down or overlays it, remembered per site.)
The cell magic (%%apl) runs APL code and displays the session’s own output, rendered in Adám’s SAX2 APL font, so results look exactly as they do in Dyalog:
Assignments are shy, just like in the Dyalog session, so the m← line above printed nothing. The line magic (%apl) instead evaluates one expression and returns it as a Python value:
[3, 6, 9, 12]
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Because the line magic returns a value, you can store it in a Python variable. Scalars come back as numbers or strings, vectors as lists, and higher-rank arrays as nested lists:
To suppress a cell’s output, end the last line with a ;:
⎕← displays a value explicitly, which is how you show something that would otherwise be shy:
To use numpy, just pass the result of %apl into np.array:
The fibonacci sequence:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]
Explanation:
1 1: Initial seed (first two Fibonacci numbers){⍵,+/¯2↑⍵}: Function that appends the sum of the last two elements⍣15: Apply the function 15 times⊢: Identity function, passes the initial argument (1 1) to the iterationPrime number sieve:
Explanation:
⍳50 generates integers 1 to 50⍵∘.|⍵ creates a 50x50 matrix of divisibility (1 if divisible, 0 if not)0= inverts the matrix (1 for non-divisible)+⌿ sums columns, counting non-divisors for each number2= checks if count equals 2 (prime property)⍵× multiplies result with original numbers, keeping primes~0 removes zero from the resultThe magics are a thin layer over the Apl class, which you can use directly in scripts, tests, and other tooling. Calling the session runs code and returns the output exactly as Dyalog formats it (or None if there’s no output); APL errors raise AplError:
Square brackets move values between Python and the workspace, in both directions, and take any expression:
fn lifts an APL function into a Python callable (one argument applies it monadically, two dyadically):
Sessions shut themselves down at process exit; use close, or a with Apl() as apl: block, to do it sooner:
⎕ or ⍞ can’t work in a notebook, so it raises an error. The session survives.:If, wedges the interpreter with no way back (Dyalog/ride#1401). aplnb detects this, tells you, and starts a fresh session, but workspace state is lost when it happens.%apl transfers values with ⎕JSON, so it’s limited to arrays and scalars that JSON can represent, serializing to at most 32767 characters. For bigger data, write a file from APL instead.To start learning APL, follow the 17 video series run by Jeremy Howard, and have a look at the study notes. The ] user commands mentioned there, such as ]Help ≠, work in aplnb too.