Notes from the fast.ai APL study group

APL is a way to learn and teach math. It’s a beautiful and powerful notation that challenges you to think about programming in new ways.
Author

Wasim Lorgat

Published

July 5, 2022

Here are my notes for day 1 of the FastAI array programming study group run by Jeremy Howard. Check out the official thread on the FastAI forum for up-to-date info. Any mistakes are mine - please let me know if you spot one.

Diagram in a juggling notation (via Wikipedia).

Why learn APL?

[Jeremy gave a personal answer here. I’ve paraphrased here and there, and reframed it in the third person, hopefully without changing his intended meaning.]

APL is a way into learning and teaching math

Math is beautiful… but also very frustrating. It’s inconsistent, the notation is hard to lookup, and it’s hard to understand what things mean in a very abstract way when we can’t experiment with them. APL helps us understand math, thus it helps us teach math.

Jeremy teaches his daughter and her friend math. He found that there were concepts that he found very difficult to teach in traditional abstract ways. In particular, he spent an hour trying to teach them sequences and series with very little progress. He then tried it again with numpy and APL and it clicked much more easily.

There’s emmense beauty and power in notations

In a previous live coding session, Jeremy talked about regex being a powerful notation. Powerful notations are key to furthering human intellectual development. You see this repeatedly in many domains, particularly math and physics. New ideas take hundreds of years to figure out become far simpler once someone finds the right notation. Notations grant us the ability to manipulate symbols to develop new ideas. Examples include algebra, zero, and even juggling!

APL is a very powerful notation, not just for math but for a range of topics that use similar concepts as math. For example, Aaron Hsu’s PhD used APL to build a compiler on the GPU.

APL will challenge you to think about programming in new ways

APL is an independently developed branch of programming with a rich history. APL as a notation has been developed since the 1960s, largely independently to other branches of programming languages. If you never learn about it, you miss out on an entire branch of languages with an incredibly rich history. Jeremy felt that learning array programming did more for his programming skills than any other language he’s learned.

Setting up Dyalog in Jupyter

Install Dyalog

We’ll use Dyalog, an APL dialect. The first step is to install Dyalog from their download page.

Install the Dyalog Jupyter kernel

Although Dyalog comes with an IDE, we’ll use Jupyter notebooks. Make sure that you’ve installed Jupyter notebook. Then install Dyalog Jupyter kernel following their installation instructions. Although their instructions say that Anaconda is required, I didn’t need it on MacOS.

Create a notebook with the Dyalog kernel

Click New, then Dyalog APL.

Create a Dyalog notebook in Jupyter by clicking New then Dyalog APL.|Create a Dyalog notebook in Jupyter by clicking New then Dyalog APL.

You should now be able to write Dyalog directly in your notebook! Try it out:

1 2 3 - 4 5 6
¯3 ¯3 ¯3

Tips for a smoother dev environment

APL uses a variety of glyphs like the ¯ glyph in the previous output. To make these easier to type in your notebook, you might want to use the APL language bar. It lets you use backtick (`) as a prefix to enter glyphs. For example, <backtick>2 is a shortcut for the ¯ glyph. You can type <backtick><space> to enter a normal backtick again. It also adds a bar to the top of the page with all of the possible glyphs:

The APL langauge bar: a horizontal list of APL gylphs.

Hovering on a glyph shows a its name and keyboard shortucts:

Hovering on the minus sign glyph shows ‘negate minus’.

A top-down learning plan

Most tutorials teach APL bottom-up; they go really deep into one topic. FastAI instead strives for top-down teaching. Therefore, we’ll try the approach of learning all of the glyphs first, as simply and quickly as we can. This has the added benefit that the documentation will become useable, since one glyph’s documentation often contains examples that use other glyphs.

You can find a table of all of the gylphs here:

Tables of APL glyphs: primitive functions, and primitive operators, via Dyalog docs.

A good way to learn new concepts in APL (and in general) is to look at an example, try to predict what it’ll do before you run it, then run it and compare with your prediction. APL documentation is filled with examples which makes this approach even more powerful. The documentation will often include multiple examples as separate elements of an array.

For example, you should read the example for negate:

- 3.2 ¯7 0
¯3.2 7 0

as three examples:

- 3.2
¯3.2
- ¯7
7
- 0
0

We then went on to learn about the following. My notes are sparse at this point - I highly recommend you check out the video instead!

  • Minus sign; its monadic (negate) and dyadic (minus; subtract) forms.
    • We also use operator names when reading APL expressions. For example, ¯2 reads “negate 2”.
  • Arrays - we needed to know about arrays to understand minus’ examples.
    • In APL you create an array (like a vector in math and a tensor in deep learning) by adding spaces between elements.
  • Functions; monadic versus dyadic functions.
    • Each glyph has two forms: monadic and dyadic. This isn’t the same as “monads” in Haskell - it simply means a function that takes one argument. In APL you don’t write functions like f(x,y,z). You either write them as f x if there’s one argument (monadic), or x f y if there are two (dyadic).
  • Plus sign; its monadic (conjugate) and dyadic (plus) forms.
  • Complex numbers - we needed to know about complex numbers to understand conjugate.

Q&A

Are parentheses used for clarifying expressions in APL?

Not really. Since the precedence rules in APL are so simple, people don’t tend to use parentheses for clarity, but rather only if they’re absolutely needed.