Too long; didn’t read

Don’t be afraid to ask questions. Don’t be afraid to ask for help when you need it. I do that every day. Asking for help isn’t a sign of weakness, it’s a sign of strength. It shows you have the courage to admit when you don’t know something, and to learn something new. –Barack Obama

I started this from wanting to write down the few things that would have made my learning easier had I known them from the beginning. Many of those things (inevitably) now seem obvious, and this is probably part of the problem I faced at the time: the simple bits that everyone assumes everyone understands are only simple and obvious once you know them. Given that this book ended up creeping in scope, perhaps we should return to that original aim. What are the top-10 things that you really should take the time to understand from day 1, from practical to theoretical?

  1. Scalar extension is vital to understand (but also pretty hard to miss).

  2. Arrays are not “list of lists”: rank is not depth. Make sure you really understand the difference.

  3. Corollary: a vector of n items is not the same as a 1×n array.

  4. Arrays can only contain scalars. This means that everything in an array must have rank 0, and thus higher-rank elements must be enclosed before they can go in an array.

  5. Cells are not equal to the element(s) they contain. Understand why pick () is different from squad ().

  6. Enclosures are not shown in output by default. Turn on boxing with ]box on -s=min|mid|max! This also helps with visualising rank.

  7. Understand the leading axis idea and a lot of other things start to make sense.

  8. Study the rank () operator early and don’t stop until the penny drops.

  9. RIDE: Shift-ctrl-backspace/return moves through your command history.

  10. RIDE: Esc ‘fixes’ a function – change that immediately to command-s!

Final thoughts

Learning APL is a rewarding pursuit. It certainly forced me to reexamine many calcified patterns in my own brain on what programming “should be like”. It was frustrating at first, feeling that the process of learning a new language was slower than usual. If you can resist the reaction that this is somehow the fault of APL (“It’s unreadable!”), you’ll soon conquer that initial small hump on the learning curve.

The other thing that I’ve found interesting is how many of your established “best practices” have evolved in completely different directions for APL. Aaron Hsu talks about this more eloquently than I ever could in his talk on APL patterns and anti-patterns, but I’d like to highlight the following:

Good APL follows a set of best practices that directly contradict and conflict with traditional programming wisdom. Indeed, APL design patterns appear as Anti-patterns in most other programming languages. –Aaron Hsu

This cognitive dissonance is one reason why some “computer people” hate APL. For me it’s one of the main draws: two fingers to Uncle Bob, the Gang of Four, and all of their ilk, the buzzkills of the software world.

Writing APL code the same way you write traditional software only defeats both sanity and efficiency. –Aaron Hsu

Idioms, not libraries

When splitting a string on a delimiter is as easy as

',' (≠⊆⊢) 'one,two,three'
Rebuilding user command cache... done
┌───┬───┬─────┐ │one│two│three│ └───┴───┴─────┘

there is no value in having a string library that needs importing and a stringsplit function. In fact, avoid naming things if you can, and if you must, only name things so close to their use that the definition can be seen without scrolling.

It’s kind of the polar opposite of any DRY rule you will have had drilled into you from the beginning. Good APL code reuses short idioms by “copy & paste” so as not to obscure functionality.

Implicit is better than explicit (sometimes)

If you’re a Python programmer indoctrinated to believe in the Zen of Python ball and chain, you’re probably cringing. In APL, the tacit style allows you to compress more meaning into the glyph count, like, for example the string split example above. This means that short phrases can be made even shorter, and thus become idioms that can be recognized as whole “words”. See Aaron Hsu’s Co-dfns project for an awe-inspiring masterclass in what this can look like when you take this approach to its logical conclusion.

Economy of representation is a virtue

The fewer keystrokes needed for your implementation, the easier it is to discover bugs by inspection, and the more of the system architecture you can hold in your head. This leads to increased confidence when making changes that these will function as intended in the larger context.

Ken wrote the following:

The utility of a language as a tool of thought increases with the range of topics it can treat, but decreases with the amount of vocabulary and the complexity of grammatical rules which the user must keep in mind. Economy of notation is therefore important. Economy requires that a large number of ideas be expressible in terms of a relatively small vocabulary. A fundamental scheme for achieving this is the introduction of grammatical rules by which meaningful phrases and sentences can be constructed by combining elements of the vocabulary. –Ken Iverson

Somewhere in the mists of time, that idea was forgotten in mainstream languages. Look at your Java, your C++, your Rust, your Go – even your Python, a language which prides itself on its clean syntax. Why do you have to type all that stuff to get things done?

Acknowledgements

aplorchard

[Illustration by Razetime on APL Orchard]

I’d like to thank the bunch of mysterious pseudonyms that hang out on the APL Orchard chat room who patiently answered every question I asked. It’s the main reason I persisted with APL. In no particular order, an incomplete list: Adám, rikedyp, RGS, ngn, Bubbler, rak1507, Marshall, dzaima, Razetime, Elias Mårtenson, Morten Kromberg and many others. I go under the mysterious pseudonym xpqz – pop in and say hello.