Enhancements in Dyalog v20.0: Arrays, Namespaces, Composition, Inline Tracing - Asher Harvey-Smith

Lobsters Hottest Tools

Summary

Dyalog v20.0 introduces array notation, inline tracing, and the behind composition operator, significantly enhancing the APL coding experience and debugging efficiency.

<p><a href="https://lobste.rs/s/boef7v/enhancements_dyalog_v20_0_arrays">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 06/26/26, 02:05 AM

### TL;DR Dyalog v20.0 introduces array notation (direct multi-line array writing), inline tracing (step-by-step expression decomposition), and the behind composition operator (preprocessing the left argument), significantly improving coding experience and debugging efficiency. ## Array Notation One of the biggest changes in version 20 is array notation, which allows you to write arrays directly in a multi-line text-like form, without having to piece them together or construct them using functions. ### Vector Notation Use parentheses `()` and diamond `⋄` or newlines to separate elements. For example: `` (New York ⋄ 2025 + 1) `` creates a two-element array: the first element is the character vector `'New York'`, the second is the result of the expression `2026`. Each element in the array can be any expression, not just constants. ### Matrix Notation Square brackets `[]` define a matrix, with each row placed inside a bracket layer. For example: `` [ (3 1 2 3) ] [ (4 5 6 7) ] `` is equivalent to the matrix with rows `3 1 2 3` and `4 5 6 7`. Higher dimensions can be achieved by nesting: if each position contains a matrix instead of a vector, you define a three-dimensional array. ### Editor Experience Array notation is fully supported in the IDE. Enter the expression above and press Enter to see the result. Click the "Show as array notation" button to display the output as a formatted multi-line array notation — and that output itself is valid APL syntax. You can edit the block directly, e.g., change text or numbers, and re-evaluate it. The editor also has an "Edit with array notation" button that expands the array content into array notation form for free modification. Afterwards, you can normalize the edited result via "Edit" → "Reformat" (or slash on the numeric keypad). ### Namespace Notation Similarly, use parentheses `()` with `name: value` to define namespaces. For example: `` (foo: 1 2 3 ⋄ bar: 4 5 6) `` creates a namespace containing the names `foo` and `bar`. Because an empty pair of parentheses `()` is ambiguous (empty vector vs. empty namespace), it is defined as an empty namespace (since other ways to write an empty vector already exist, such as `''` or `⍬`). Array notation supports nesting perfectly: you can embed matrices or other structures inside a namespace. ## Inline Tracing The inline tracer is a debugging tool introduced in version 20 for step-by-step observation of the execution order and intermediate results of each primitive in a complex expression. It is more fine-grained than traditional line-by-line tracing, advancing one primitive at a time. ### How to Use In the session, select an expression (e.g., a function call), then choose the menu "Actions" → "Inline Trace", or press the shortcut Ctrl+Alt+Enter. The tracer enters a mode that decomposes the expression into individual primitive steps, showing the current arguments and result at each step. ### Example For the expression `(⌈/⍵)÷10`, inline trace first shows `⌈/` being called, with right argument `⍵` and no left argument (monadic call). Stepping forward, it computes `⌈/`, then shows the division operation, with left argument the result of `⌈/` and right argument `10`. Another more complex example: `(⊢/¨⊢)` on a nested application. Inline trace can show step by step how each `⊢/` operates on each element of `⍵`, eventually mixing to produce the result. This is extremely useful for understanding execution order in uncommented code or for beginners. ## Behind Composition Operator Behind is a new composition operator that fills the gap where previously you could only preprocess the right argument (using compose `∘`) but not the left argument. ### Background Compose `∘` preprocesses the right argument. For example, `neg recip` (reciprocal then negate), where recip preprocesses the right argument. Behind `⍤` (symbol is `⍤`, but described in text) allows preprocessing the left argument. The definition of dyadic behind is: `X f⍤g Y` is equivalent to `(f X) g Y` — first transform the left argument `X` with `f`, then pass it to `g`. If the left argument is omitted, behind duplicates the right argument as the left argument (in monadic calls this is equivalent to `(f Y) g Y`). ### Examples - **Membership check**: We want to check if the word `'dog'` is contained in the list of character vectors `'dog' 'cat' 'fish'`. Using `'dog' ∊ 'dog' 'cat' 'fish'` directly would scan each letter due to broadcasting. The traditional approach is to enclose the entire `'dog'` with `⊂`. Now we can use behind: `⊂⍤∊`. Then define the function `word_member ← ⊂⍤∊`, which can be used anywhere, even in tacit expressions. - **Minimum mask**: Given the list `10 15 10 20`, we want a mask of positions equal to the minimum. One can write `(⌊⍵) = ⍵`, but using behind we can write `⌊⍤=`, where the left argument is duplicated. So the expression directly becomes `⌊⍤=`, concise. - **Conditional filtering**: `behind replicate` is one of the most useful scenarios. For example, to keep positive numbers from `1 -2 3 -4 5`, we can write `(×⍤) / ⍵` (where `×` is bound to 0 for greater-than-zero testing). The actual form might be `(×∘0)⍤/` (assumed form). When shown with inline tracing, you can see `×` first applied to the left argument to produce a mask, then replicate executes. Behind makes many operations that previously required temporary definitions or sandwiching more direct, especially suitable for use in tacit style. ## System Functions (Brief Mention) Version 20 also introduces system functions `⎕V`, `⎕VGET`, and `⎕SH` (quad shell), but due to time constraints they were not detailed in the talk. --- **Source**: Enhancements in Dyalog v20.0: Arrays, Namespaces, Composition, Inline Tracing - Asher Harvey-Smith (https://www.youtube.com/watch?v=1IaLs96lEEg)

Similar Articles

A principled rethinking of array languages like APL

Lobsters Hottest

The article proposes a principled rethinking of array languages like APL by modeling variables as functions of input dimensions, aiming to improve readability and error checking compared to traditional approaches.

@justloveabit: https://x.com/justloveabit/status/2055263377006747820

X AI KOLs Timeline

Introducing the new version of Claude Code 2.1.142 in combination with CodeGraph and MCP, which greatly improves the efficiency of exploring large codebases through a local semantic knowledge graph, with a 92% reduction in tool calls and a 71% speed improvement.

Typst: Designing for Incrementality

Lobsters Hottest

Typst uses constrained memoization (comemo) and pure function design to make the language and compiler work together, achieving efficient incremental compilation and real-time preview. The article details the design ideas of layout caching, module evaluation memoization, function purity, and the introspection system.

Symmetries in boolean scans

Lobsters Hottest

The article explores symmetries in boolean scans within array languages like APL, discussing optimizations for folds and scans through functional equations and algorithmic insights.