去年Rust在Stack Overflow调查中连续8年霸榜"最受喜爱语言",但83%的受访者承认它的学习曲线像一堵墙。有人想:如果能把内存安全塞进更易学的范式里呢?
一个独立开发者真的动手了。他叫Slap,不是拍巴掌,是Stack Language with A Purpose的缩写—— purpose就是给栈语言装上借检查器。
这事在技术圈炸出了1.8万GitHub星标。要知道,上一个靠"缝合怪"设计出圈的PL(编程语言)还是Zig,而Slap的野心更大:它要把Forth的后缀语法、Haskell的类型推导、Rust的线性类型,全塞进一个运行时。
栈语言的美与丑
Slap的核心语法看着像密码:`0 1 20 (swap over plus) repeat drop`。这是计算第20个斐波那契数,全程没递归、没变量名,纯靠栈操作。
作者自己承认"后缀语法很丑,但强大"。他计划后期加入Uiua风格的符号,让你写代码时"像个巫师":`0 1 20 (: ↷ +) ⍥ ↘ 2765 = !`
受不了隐式栈操作的人可以用`let`显式绑定。同一道题两种写法:
隐式版本:`[1 2 3 4 5] (sqr) map sum`
显式版本:`[1 2 3 4 5] 0 ('x let 'y let x x mul y plus) fold`
两种都通过类型检查,都得出55。Slap不强迫你选边站,但隐式版本少敲15个字符——在栈语言里,字符数直接对应认知负荷。
借检查器怎么塞进栈里
Slap的真正卖点不是语法,是它拒绝让你做什么。
参数类型系统(Hindley-Milner风格)拦住数据类型错配:`[1] [2.0] cat`会直接报错,因为不能拼接int列表和float列表。
线性类型系统(Rust式借检查器)拦住内存乱搞。你不能复制指针,也不能丢弃指针:
`42 box dup` → 类型错误:dup需要可复制类型,得到的是box
`42 box drop` → 类型错误:drop需要可复制类型,得到的是box
对box只有四条路:借出(lend)、变异(mutate)、克隆(clone)、释放(free)。
看这段文件句柄操作:`[1 2 3] box (len) lend 3 eq assert free`。先装箱,借出只读快照算长度,断言等于3,最后释放。双free、use-after-free、内存泄漏,在编译期就被掐死。
作者说线性类型对文件句柄和线程协调同样有效——这部分实现还在路上。
栈的多重身份
Slap的栈不是简单的FILO存储。类型系统允许你把它当元组、闭包、函数组合器用,而不会混淆:
当元组:`(1 2) apply plus` 得3
当闭包:`'make-adder ('n let (n plus)) def`,然后`5 make-adder 3 swap apply` 得8
当函数管道:`(1 plus) (2 mul) compose (3 sub) compose (sqr) compose`,对5执行得81
传统语言要声明函数类型,栈语言有类似的"栈效应"概念。Slap的类型推导自动算这个,但你可以显式标注来加强约束:
`'square (dup mul) [int lent in int move out] effect check def`
这行说:square接受一个int的只读借用,输出一个int的所有权转移。标注能描述更古怪的效应,比如零效应、多返回值、带线性参数的泛型效应。
没有GC,也没有秘密
Slap的运行时很薄:无垃圾回收,无隐式堆分配。所有东西默认在栈上,除非你主动`box`送进堆。
作者坦承"栈通常比堆慢",但Slap的透明语义强迫你直面这种权衡——没有魔法,没有黑箱。
GitHub讨论区有人质疑:栈语言的小众生态加上Rust的陡峭曲线,会不会负负得正?作者回复说目标用户是"已经懂Rust、想用更轻量的语法写系统代码"的人。
项目目前处于早期原型阶段,标准库几乎空白。但1.8万星标里有多少是"收藏了等于学了",有多少会真的用它写生产代码——这个比例本身,可能比Slap的语法更值得观察。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.