Rejoice:凿掉位置之后,袋中剩余的那些
Rejoice: What Remains in the Bag After Position Is Chiseled Away
Rejoice 是 Devine Lu Linvega(Hundred Rabbits,居于船上的加拿大艺术家/程序员二人组)于2026年4月发布的一门编程语言。它的程序状态不是栈,不是数组,不是变量绑定——而是一个"袋"(multiset):一个无序的物品集合,其中只有种类和数量有意义,位置完全不存在。程序是一系列分数:owl/cat^2 的意思是"若袋中有两只猫,则以一只猫头鹰替换之"。分数的分母描述从袋中移除什么,分子描述向袋中添加什么。依次尝试每个分数,能触发的就触发,不能的则跳过,程序结束时袋中的剩余物就是运算结果。逻辑门(NOT、OR、AND)、算术(加减乘除)、Fibonacci 数列——全部从这一套分数机制中自然涌现,无需任何额外的原语。
在 SAE 框架里,"已构"是那些已被完整命名、成为凿构循环终点的形式。栈式拼接性计算(Forth 及其后裔)是已构:它将空间隐喻深植于计算的核心——元素有位置(顶部、底部),压入与弹出是基本操作,程序的意义由元素在栈上的顺序决定。这是坚实的构,计算机科学为其命名、优化、并将其推广为范式。Rejoice 的凿子是:移除位置。袋是无序的,元素没有编号的座位,只有数量的多寡。当位置被凿去之后,计算依赖的仅剩下种类与数量——而这正是分数算术的天然语言。余项就在这里:不是栈顶,不是地址,不是指针——而是袋中剩余的符号实例。"余项"在此既是比喻,也是字面:每次分数应用,分母从袋中被减去,剩下的是数学意义上的差。这门语言的运算结果,是字面意义上的 remainder。
更深的一层在于:逻辑从算术中涌现。通常我们认为算术建立在逻辑之上——逻辑门→晶体管→处理器→算术运算。Rejoice 倒置了这一顺序:NOT 门、OR 门、AND 门全部通过分数序列实现,不需要任何独立的布尔原语。逻辑成为算术的余项,而不是反过来。这一倒置并非设计目标,而是袋计算内在结构的自然产物——分数能够精确描述"若某符号存在于袋中"的条件,因此命题逻辑可以从分数算术中直接生长出来,就像杂草从砖缝里长出来一样。文档的书写语言本身也在表演同一个动作:Peano 的"去屈折拉丁语"(Latino Sine Flexione)是从古典拉丁语中凿去所有语法屈折变化后的余项——与 Rejoice 从栈式计算中凿去位置,是同构的姿态。记录一门语言的文字,以同样的方式被凿过。
Rejoice 的余项性此刻仍在生长。4月发布时,Devine 自称这是一个"cursed idea"(受诅咒的想法),并向精通改写系统、线性逻辑、多重集的人们求助,因为他自己也站在理解的边界上。配套的邮件列表("Rewriting Mailinglist")刚刚建立,与互动网络(Interaction Nets)的关联仍在探索(同月发布了《Pocket Nets》小册子),与热带算术(tropical arithmetic)的连接刚刚被提出。语言的标准库还未写完,语义仍在变化,创作者本人还不确定它能够完整表达什么——这正是余项的状态:已构足够清晰以被实现,但尚未被任何命名系统完整消化。一旦它被正式归入某个范畴——"多重集改写语言"或"约束式拼接性语言"——这个命名行为本身就会将它从余项固化为已构。此刻,它仍是一袋还没有名字的符号。
Rejoice 是用 Uxntal 写成的——同样由 Hundred Rabbits 设计的极简自足虚拟机,本身也是软件构造中余项美学的另一个实例。在内嵌的 REPL 里,可以直接在浏览器中运行 Rejoice 程序。用分数写程序,用袋子存储运算结果:没有位置,没有地址,没有顺序——只有在一堆无序之物中,那些还剩着的。
wiki.xxiivv.com/site/rejoice ↗Rejoice is a programming language released in April 2026 by Devine Lu Linvega of Hundred Rabbits — the artist-programmer pair who live and work on a sailboat. Its program state is not a stack, not an array, not a set of named variables. It is a bag: an unordered multiset of symbols where only kind and quantity matter, and position does not exist. Programs are sequences of fractions: owl/cat^2 means "if the bag contains two cats, replace them with one owl." A fraction's denominator specifies what to remove from the bag; its numerator specifies what to add. Each fraction is attempted in order — if it can fire, it fires; if not, it is skipped. When the program ends, what remains in the bag is the result. From this mechanism alone, without any additional primitives, emerge NOT gates, AND gates, arithmetic operations, Fibonacci sequences, and FizzBuzz.
In SAE terms, the already-construct here is stack-based concatenative computation — Forth and its descendants. The stack embeds a spatial metaphor at the heart of computation: elements occupy positions (top, bottom), push and pop are the basic operations, and meaning depends entirely on ordered slots. This is a solid construct — named, optimized, propagated as paradigm across decades of programming language design. Rejoice's chisel is the removal of position. A bag has no numbered seats; elements carry only count, not location. What remains when you strip position from computation is arithmetic over quantities — and that is exactly the natural language of fractions. The remainder, in this language, is literal: every fraction application subtracts its denominator from the bag, and what survives is a mathematical remainder. The program's output is, in the precise mathematical sense of the word, a remainder.
A second-order remainder: logic emerges from arithmetic. We ordinarily understand arithmetic as built on top of logic (logic gates → transistors → processor → arithmetic). Rejoice inverts this: NOT, OR, and AND gates are all implemented as sequences of fractions, with no independent Boolean primitive anywhere. Logic becomes the remainder of fraction arithmetic, not its foundation. This inversion is not a design goal — it is a natural product of the bag's structure, which can express "if this symbol is present in the bag" as a direct condition in fraction notation, allowing propositional logic to grow from arithmetic the way weeds grow through pavement. The documentation language enacts the same gesture: Peano's Latino Sine Flexione is what remains of Classical Latin after all grammatical inflection has been stripped away — the same structural chisel applied to natural language that Rejoice applies to computation. The text that records the language has been chiseled in the same way the language itself chisels computation.
Rejoice's remainder quality is still growing. On release in April 2026, Devine called it a "cursed idea" and asked practitioners of rewriting systems, linear logic, and multisets for help — because he himself stood at the edge of what he could understand. The mailing list was just established; the connection to Interaction Nets is still being explored (a Pocket Nets zine was released the same month); the relationship to tropical arithmetic has only just been named. The language's standard library is incomplete; its semantics are still changing; the creator doesn't yet know what it can fully express. This is precisely the condition of the remainder: sufficient clarity to be implemented, but not yet fully digested by any naming system. The moment it gets filed under "multiset rewriting language" or "constraint-based concatenative language," that naming act will crystallize it from remainder into construct. For now, it remains a bag of symbols without a proper name.
Rejoice runs on Uxntal — Hundred Rabbits' own minimal self-sufficient virtual machine, itself another instance of remainder aesthetics built into software infrastructure. A browser-embedded REPL is available at the link below. Write programs as fractions. Store computation as an unordered bag. No positions, no addresses, no sequence in the state — only what remains, among a pile of unordered things, when the fractions have finished firing.
wiki.xxiivv.com/site/rejoice ↗