起这个念头的契机是看到连 M$ 都动心思搞 JS 生成器了 (然而不得不吐槽的是, 这语言看起来跟 JS 简直一个德行). 而模仿的对象则是 CoffeeScript, 可是我又不想去分支 CoffeeScript 改点语法什么的改成 LatteScript 或 CappuccinoScript (我对 Coffee 的某些语法不很满意), 于是乎自己折腾了一个.
不过另一方面, 这个编译器 (暂定名是 Stekinscript) 也不是完全无中生有, 而是从我的毕业项目修改过来的. 要说这样有什么不好的话, 就是 --- 这东西用 C++ 实现的 (准确地说是 C++11); 要说有什么好的话, 就是貌似这样可以直接集成 v8, 嗯 (自黑一下, 我没考察过这个, 也没有做这个事情的计划).
下面介绍一下这个语言本身, 撇开日常的什么分支语句啦函数定义返回这些 (详情可参考文档), 先说说重点.
首先 Stekinscript 支持缩进语法, 类似 Python 跟 CoffeeScript. 代码很重要的一点就是要看着舒服不是么?
其次就是非强制类型, 强制类型给人的感觉呢, 就像三岁小孩子学写字旁边有个执戒尺的先生一样, 错一点就打手, 我们已经是断奶的程序员了好么, 所以什么 Dart 就先搁下不用了.
最后是实际使用的感觉, 这一点我排斥 CoffeeScript 的 lambda 语法如
(x)-> x * x
这种. 要知道输入类似 ->
这样的符号两个字符都在右手无名指跟小指区, 还是一上一下, 而且减号不用按住 Shift 而大于号又需要, 这是有多别扭设计语言的人没知觉么? 还是说已经练成星际争霸九段这点微操不算什么?吐槽就到此为止, 下面贴个 Stekinscript 的例子
x: []
setTimeout(():
if x.length = 10
return
x.push(document.getElementById('input').value)
, 2000)
x
为一个空列表. 然后调用 setTimeout
函数, 第一个参数是无参 lambda, 其实呢, 刚才黑 CoffeeScript 那么多, 现在只是把 ->
改成了 :
作为 lambda 的标识 (我是不是该去买点节操了); 第二个参数是 2000, 在上面例子的最后一行. 注意到这一行 , 2000)
的缩进与 setTimeout
所在的行缩进一致表示它与上面 lambda 的函数体并不是一路的, 而是继续之前的 setTimeout(():
这一行.在函数体中是一个分支语句,
if
的条件不需要括弧 (顺便黑一下 Go 语言, 没有括弧而在后面加上个大括号看起来不刺眼么), 分支中 x.length = 10
是在判断两个表达式是否相等而不是赋值运算 (实际上 Stekinscript 暂不提供任何赋值运算符, 包括 +=
这种); 分支成功块中只有一句 return
, 否则继续执行下面的 x.push
一行, 缩进表示很明显了吧.大家可以准备一下吐槽这个了 (誘受的口吻...)
话说既然抄了 Python 的缩进语法, 一不做二不休, 列表切片我也笑纳了. 只不过 Stekinscript 中的列表切片稍微有些不一样, 是以逗号分隔切片项的, 如
x[2, 4]
或 y[,, -1]
这样. 这么做的原因跟 lambda 的语法有些冲突 (虽然后来用类似解决算符优先的方式解决了此问题), 如 x[(m): 4]
这个写法可以认为是以匿名函数 (m): 4
作为键去索引字典, 又可以误认为是以 (m)
为起始位置 4 为结束位置切片. 于是就弃用了冒号而改为逗号作切片分隔符.Python 水太深, 还有很多奇妙的语法, 比如 list comprehension, 不过本着单抄一门语言是抄袭, 但如果抄很多语言那一定是借鉴的指导思想, 其它的语言特性就从别的地方挖好了. 下面再介绍一个语法特性替代 list comprehension, 这个称之为管道, 如下
x: [1, 1, 2, 3, 5]
y: x |: $ * $
z: x |? $ % 2 != 0
y
的取值将是 [1, 1, 4, 9, 25]
而 z
的取值为 [1, 1, 3, 5]
.在管道操作符右侧的表达式中, 出现的
$
表示列表中的每个元素, $i
(虽然上例中没出现过) 表示元素索引.对于映射管道, 管道右侧的表达式是映射元素的方式; 而对于过滤管道, 右侧的表达式则是过滤元素的条件.
多个管道还可以套接起来, 比如
x: [1, 1, 2, 3, 5]
y: x |? $ % 2 != 0 |: $ * $
y
先经过过滤管道再经过映射管道, 最后值为 [1, 1, 9, 25]
.(看来我果然是个发明各种奇葩语法的奇葩)
更多例子可以参考案例测试集, 其中每个后缀为 stkn 的文件是 Stekinscript 源码, 而对应的 expected 后缀文件则是参考输出文件.
如果现在想体验 Stekinscript 的话, 请参考这篇文档, 目前已测试 ArchLinux/Ubuntu 系统.
接下来, 鄙博客将持续介绍