瞧瞧, Slap !它简直就是语言的奇美拉:
简洁
Slap 是一种栈式语言。后缀语法虽然丑陋,但功能强大:
-- twenty fibonacci numbers (no recursion) 0 1 20 (swap over plus) repeat drop 6765 eq assert
我最终会添加类似Uiua的字形,让你感觉自己像个巫师:
0 1 20 (: ↷ +) ⍥ ↘ 2765 = !
那些厌恶隐式堆栈操作的人可以使用let代替:
-- sum of squares (tacit) [1 2 3 4 5] (sqr) map sum 55 eq assert -- sum of squares (explicit) [1 2 3 4 5] 0 ('x let 'y let xx mul y plus) fold 55 eq assert
安全的
Slap真正的力量在于它做不到的事情。
参数类型(如Hindley-Milner类型)可防止数据不匹配:
[1] [2.0] cat -- TYPE ERROR: type variable conflict -- expected: int list -- got: float list
线性类型(例如类似 Rust 的借用检查器)保护已分配的内存免受泄漏、损坏、篡改和遗弃。您既不能复制也不能丢弃指针(盒子):
42 box dup -- TYPE ERROR: dup requires copyable type, got box 42 box drop -- TYPE ERROR: drop requires copyable type, got box
对于盒子,你必须lend 、 mutate 、 clone或free :
-- borrow a read-only snapshot with lend [1 2 3] box (len) lend 3 eq assert free -- mutate in place [1 2 3] box (4 give) mutate (len) lend 4 eq assert free -- clone into two independent boxes [1 2 3] box clone (4 give) mutate (len) lend 4 eq assert free () lend 3 eq assert free
此 API 可防止双重释放、释放后使用和忘记释放等经典问题。
线性类型也非常适合文件句柄和线程协调。敬请期待!
Slap 的栈非常灵活。您可以安全地将它们用作元组或闭包,而不会混淆类型系统:
-- it's a tuple (1 2) apply plus 3 eq assert -- it's a closure 'make-adder ('n let (n plus)) def 5 make-adder 3 swap apply 8 eq assert -- it's a function (1 plus) (2 mul) compose (3 sub) compose (sqr) compose 5 swap apply 81 eq assert
在某些语言中,你可以声明函数类型。类型化栈语言有一个类似的概念,称为“栈效应”。Slap 类型检查器会自动为你推断这些类型,但你也可以手动添加它们以增强清晰度/强制执行:
-- double = n -> n * 2 'double (2 mul) def -- square : int -> int -- square = n -> n * n 'square (dup mul) [int lent in int move out] effect check def
Slap 的注释足够详尽,可以描述奇特的堆栈效应:
-- no effect 'noop () [] effect check def -- return multiple values 'hello-world ("hello" "world") [str move out str move out] effect check def -- linear parametric effect 'pal ((dup reverse cat) mutate) [ 'a list 't own in 'a list 't own out ] effect check def
快速地
没有垃圾回收!没有秘密分配!所有数据都存储在栈上(除非你用box把它送到堆上)。
栈通常比堆慢。Slap 的透明语义迫使你权衡这种利弊。
Slap 可以快速解决 Project Euler 前五十道题中的大部分。以下是前十道题:
| 1 | 3毫秒 | 问题 | 解决方案 |
| 2 | 3毫秒 | 问题 | 解决方案 |
| 3 | 3毫秒 | 问题 | 解决方案 |
| 4 | 102毫秒 | 问题 | 解决方案 |
| 5 | 3毫秒 | 问题 | 解决方案 |
| 6 | 3毫秒 | 问题 | 解决方案 |
| 7 | 542毫秒 | 问题 | 解决方案 |
| 8 | 10毫秒 | 问题 | 解决方案 |
| 9 | 40毫秒 | 问题 | 解决方案 |
| 10 | 7298毫秒 | 问题 | 解决方案 |
| … | … | … | … |
小的
slap.c是大约 2,000 行糟糕的 C99 代码。
还可以更小一些——我相信我可以在不牺牲可读性或性能的前提下再精简约 500 行代码。
它既是词法分析器,又是类型检查器,还是栈评估器。
如果 Slap 的架构能够容纳在我豌豆大小的大脑里,那么它肯定也能容纳在你的大脑里。
简单的
Slap 有像素!使用make slap-sdl (原生)或make slap-wasm (浏览器)构建,即可获得 640×480 的 2 位灰度画布。
游戏运行时的风格和低保真美学灵感来源于Uxn 。快去看看吧!
您可以通过高效(且类型安全)(且内存安全)的托管效果与宿主系统进行交互:
'tick (handler1) on 'keydown (handler2) on 'mousedown (handler3) on (render0) show
人生游戏
'cell ( H plus H mod W mul swap W plus W mod plus nth ) def 'neighbors ( 'cy let 'cx let 'gs let gs cx 1 sub cy 1 sub cell gs cx cy 1 sub cell plus gs cx 1 plus cy 1 sub cell plus gs cx 1 sub cy cell plus gs cx 1 plus cy cell plus gs cx 1 sub cy 1 plus cell plus gs cx cy 1 plus cell plus gs cx 1 plus cy 1 plus cell plus ) def 'step ( 'g let list 0 'i let (i N lt) ( i W divmod 'y let 'x let 'gxy neighbors 'n let 'gi nth 1 eq (n 2 eq n 3 eq or) (n 3 eq) if (1) (0) if give i 1 plus 'i let ) while ) def 'tick ( drop drawing 0 eq (step) () if ) on (... render grid ...) show
点
'tick ( ... -- Flee from mouse dist2 10000 lt mx -1 neq and ( vx dx sign 6 mul plus 'vx let vy dy sign 6 mul plus 'vy let ) () if -- When stopped, sneak back home vx abs vy abs plus 2 lt ( hxs i get x sub 'hdx let hys i get y sub 'hdy let x hdx sign plus 'x let y hdy sign plus 'y let ) () if ) on
蛇
'tick ( drop 1 plus state 1 eq ( dup 6 mod 0 eq ( -- move head in current direction dir 0 eq (hx hy 1 sub) ( dir 1 eq (hx 1 plus hy) ( dir 2 eq (hx hy 1 plus) ( hx 1 sub hy ) if) if) if -- wall/self collision → death -- eat food → grow, else drop tail ) () if ) () if ) on
更多的
请自行查看所有示例!