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

Lobsters Hottest 工具

摘要

Dyalog v20.0 引入了数组符号、内联跟踪器和 behind 组合运算符,显著提升了 APL 编码体验和调试效率。

<p><a href="https://lobste.rs/s/boef7v/enhancements_dyalog_v20_0_arrays">Comments</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/26 02:05

### TL;DR Dyalog v20.0 引入了数组符号(直接编写多行数组)、内联跟踪器(分步骤解析复杂表达式)和 behind 组合运算符(预处理左参数),显著提升了编码体验和调试效率。 ## 数组符号 版本 20 最大的变化之一就是数组符号,它允许直接以类似多行文本的形式编写数组,而不再需要逐个拼接或使用函数构造。 ### 向量符号 使用括号 `()` 和菱形符号 `⋄` 或换行符分隔元素。例如: ``` (New York ⋄ 2025 + 1) ``` 会创建一个两元素数组:第一个元素是字符向量 `'New York'`,第二个元素是表达式 `2026` 的结果。数组中的每个元素可以是任意表达式,不限于常量。 ### 矩阵符号 方括号 `[]` 用于定义矩阵,每一行放在一个括号层内。例如: ``` [ (3 1 2 3) ] [ (4 5 6 7) ] ``` 等价于矩阵 `3 1 2 3` 行和 `4 5 6 7` 行。更高维度可以通过嵌套实现:如果每个位置放的是矩阵而不是向量,就定义三维数组。 ### 编辑器中的体验 在 IDE 中,数组符号完全受支持。输入上述表达式后,按回车即可看到结果。点击“显示为数组符号”按钮可以以格式化的多行数组符号打印输出,而且该输出本身就是有效的 APL 语法——你可以直接编辑这个块,比如修改文字或数字,再重新求值。编辑器中还有一个“用数组符号编辑”的按钮,将数组内容展开为数组符号形式,允许自由修改。之后可以通过“编辑”->“重新格式化”(或数字键盘上的斜杠)将编辑结果规范化。 ### 命名空间符号 类似地,用括号 `()` 配合 `name: value` 的形式可以定义命名空间。例如: ``` (foo: 1 2 3 ⋄ bar: 4 5 6) ``` 这会创建一个包含 `foo` 和 `bar` 两个名字的命名空间。空括号 `()` 因为存在歧义(空向量还是空命名空间),被定义为空命名空间(因为已有其他方式写空向量如 `''` 或 `⍬`)。 数组符号完美支持嵌套,可以在命名空间内部再嵌入矩阵或其他结构。 ## 内联跟踪 内联跟踪器是版本 20 新增的调试工具,用于逐步观察复杂表达式中每个原语的执行顺序和中间结果。它比传统的逐行跟踪更细致,能一次只函数一个地推进。 ### 使用方法 在会话中,选中一个表达式(例如一个函数调用),然后选择菜单“操作”->“内联跟踪”,或按快捷键 Ctrl+Alt+Enter。跟踪器会进入模式,把表达式分解为单个原语步骤,每一步显示当前参数和结果。 ### 示例 例如表达式 `(⌈/⍵)÷10`,内联跟踪会首先展示 `⌈/` 被调用,右参数是 `⍵`,左参数为空(单子调用)。继续步进,它会计算 `⌈/`,然后显示除法操作,左参数是 `⌈/` 的结果,右参数是 `10`。 另一个更复杂的例子:`(⊢/¨⊢)` 在复用的应用上,内联跟踪能逐步显示每个 `⊢/` 对 `⍵` 的每个元素如何执行,最终混合得到结果。对于复杂的无注释代码或初学者理解执行顺序极其有用。 ## Behind 组合运算符 Behind 是新的组合运算符,填补了之前只能预处理右参数(使用 compose `∘`)而不能预处理左参数的空白。 ### 背景 Compose `∘` 将右参数进行预处理。例如 `neg recip`(先倒数再取反),其中 recip 预处理右参数。而 behind `⍤`(符号为 `⍤`,但文中用文字描述)允许预处理左参数。二元 behind 的定义是:`X f⍤g Y` 等价于 `(f X) g Y`——先将左参数 `X` 通过 `f` 转换,再交给 `g` 处理。如果缺省左参数,则 behind 会将右参数复制一份作为左参数(单子调用时等同于 `(f Y) g Y`)。 ### 示例 - **成员资格应用**:我们想检查单词 `'dog'` 是否包含在字符向量列表 `'dog' 'cat' 'fish'` 中。直接使用 `'dog' ∊ 'dog' 'cat' 'fish'` 会因为广播导致扫描每个字母。传统做法是先用 `⊂` 封闭整个 `'dog'`。现在可以用 behind 重写:`⊂⍤∊`。然后定义为函数 `word_member ← ⊂⍤∊`,可以到处使用,甚至在 tacit 表达式中。 - **最小值掩码**:给定列表 `10 15 10 20`,想得到等于最小值的掩码。可写为 `(⌊⍵) = ⍵`,但 using behind 可以写成 `⌊⍤=`,其中 left argument 被复制一份。这样表达式直接是 `⌊⍤= `,简洁。 - **条件筛选**:`behind replicate` 是最有用的场景。例如从 `1 -2 3 -4 5` 中保留正数,可以写 `(×⍤) / ⍵`(其中 `×` 绑定 0 表示大于0的测试)。实际写法如 `(×∘0)⍤/`(假定的形式)。展示内联跟踪时,可以看到 `×` 先应用于左参数得到掩码,然后 replicate 执行。 Behind 让许多需要临时定义或包三明治的操作变得直接,尤其适合在 tacit 风格中使用。 ## 系统函数(简要提及) 版本 20 还引入了系统函数 `⎕V`、`⎕VGET` 和 `⎕SH`(quad shell),但因时间限制未在演讲中详细展开。 --- **Source**: [Enhancements in Dyalog v20.0: Arrays, Namespaces, Composition, Inline Tracing - Asher Harvey-Smith](https://www.youtube.com/watch?v=1IaLs96lEEg)

相似文章

对 APL 等数组语言的有原则性重新思考

Lobsters Hottest

本文提出了一种有原则性的方法来重新思考 APL 等数组语言,通过将变量建模为输入维度的函数,旨在相较于传统方法提高可读性和错误检查能力。

Typst: Designing for Incrementality

Lobsters Hottest

Typst 通过约束记忆化(comemo)和纯函数设计,使语言和编译器协同工作,实现高效的增量编译和实时预览。文章详细介绍了布局缓存、模块评估记忆化、函数纯度以及内省系统的设计思路。

布尔扫描的对称性

Lobsters Hottest

本文探讨了数组语言(如APL)中布尔扫描的对称性,通过函数方程和算法洞见讨论了折叠和扫描的优化方法。