APL Inner and Outer Products: Replace Nested Loops With Array Operators
Replace nested loops in APL with vectorized inner and outer products for pairwise array computations.
27 Dec 2025, 11:09 UTC

Stop writing nested loops for pairwise array math
You need a table where every cell combines one item from the left list with one item from the right list. The first instinct in many languages is a pair of nested loops. In APL, that approach works, but it is verbose and forces you to manage indices manually. More importantly, it hides the mathematical operation from the interpreter.
The useful takeaway: APL's inner product and outer product let you express the same computation as a single array operation. The interpreter handles the iteration, which often improves readability and can open the door to optimizations such as parallel execution. The trade-off is memory: an outer product allocates a result whose size is the product of the two input sizes, so large inputs can exhaust the workspace.
Inner product: collapsing matching axes
The inner product, written f.g, applies function g pairwise along conformable axes and then reduces with f. The most common form is numeric dot product, +.×.
For two equal-length vectors, 1 2 3 +.× 4 5 6 multiplies matching elements and adds the products, producing a single scalar. For matrices, the same operator performs matrix multiplication when the inner dimensions match. If the axes do not conform, the interpreter raises a LENGTH ERROR.
Outer product: every pair, explicitly
The outer product, written ∘.f, applies a dyadic function f to every combination of elements from the left and right arguments. The result shape is the catenation of the two argument shapes: (⍴left),⍴right.
For example, 3 4 ∘.+ 5 6 produces a 2-by-2 matrix containing all four pairwise sums. You can verify this in an APL session by checking that the result has shape 2 2 and that each cell equals one left element plus one right element.
Worked example: pairwise sum table
Suppose you have two short sequences and want every pairwise sum without writing a loop:
left ← 1 2 3
right ← 10 20 30
table ← left ∘.+ right
⍴table ⍝ expected shape: 3 3
Run this in your APL interpreter's session. No special permissions are required. The result should be a 3-by-3 matrix where row i, column j holds left[i] + right[j]. Confirm the shape with ⍴table and spot-check a few cells against manual calculation.
Risk: if you substitute much larger vectors, the result matrix grows quadratically. Monitor workspace usage before running on production-sized data.
Limitations and how to verify
- Memory growth. Outer product allocates
×/ (⍴left),⍴rightcells. On big inputs this can fill the workspace and fail with a WORKSPACE FULL error. - Conformability. Generalized inner product requires matching axis lengths. A mismatch raises LENGTH ERROR before any computation runs.
- Interpreter variance. Dyalog APL, GNU APL, and NARS2000 all support these operators, but optimization and parallelization behavior differ. Do not assume an outer product is faster than an explicit loop; time both on your target interpreter.
Practical check: after running an outer product, inspect ⍴result to confirm the expected dimensions, and compare the interpreter's workspace-available indicator before and after to estimate allocation. If the shape is wrong or the workspace is exhausted, reduce the input size or tile the computation manually.
Closing
Use inner product when you need to collapse matching axes, such as dot products or matrix multiplication. Use outer product when you genuinely need every pairwise combination. Start with small vectors, verify the shape with ⍴, and benchmark on your interpreter before replacing a working loop in performance-sensitive code.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.