我开发的静态类型可嵌入脚本语言Umka的第一个版本刚刚发布。它旨在在编译成字节码的阶段将熟悉的脚本语言的灵活性与防止类型错误的功能相结合。语言的主要思想- 显式优于隐式 -是从``Python禅宗''中借用的,但是在这里它应该具有稍微不同且更明显的含义。不管促使我进行语言开发的私人或主观印象如何,我都希望该计划不是幼稚的。在切入点下,我将简要讨论该语言的功能及其创建动机。动机
动态类型化的第一个优点通常是缩短开发/调试周期并节省程序员时间。冒着引起公众不满的风险,我必须承认,我自己的经历并不能以任何方式证实这一点。每次在Python中对我的神经网络训练脚本进行较小的校正后,我都必须等待Python,NumPy,PyTorch加载,从文件中读取大数据数组,将其传输到GPU,开始处理-然后才发现PyTorch期望一个尺寸张量(1,1 ,m,n,3)代替(1,m,n,3)。我很容易承认许多人出于个人原因而喜欢使用动态类型的语言。甚至可能对动态分型的倾向或敌意与对橄榄和番茄汁的态度相同。尝试对此问题进行客观研究显然会导致不确定的结果。同时,TypeScript的普及,Python中类型注释的引入,关于Reddit和Habré的激烈讨论使我们认为,使用动态类型语言对脚本语言进行的实际识别根本不是教条,而是一种巧合,而静态类型的脚本语言具有一切权利。因此,有一种语言以猫命名,以熊命名。舌
整个语言的语法均受Go启发。语法构造的示例可以在项目页面上找到。声明变量时,可以使用带有类型推断的简写形式。值得注意的是,与指针语法中的Go规则有所不同。围棋的创造者抱怨,从字面上以下例如,C原来这里是一个不必要的复杂语法,它会更合理地引入后缀对其操作像帕斯卡尔p^
代替*p
。这正是乌姆卡所做的。译者Umka编译为字节码,然后由堆栈虚拟机执行。所有类型检查都在编译阶段完成。堆栈上的数据不再包含任何类型信息。转换器采用动态库的形式,具有自己的API和小的“包装器”(可执行文件)。源代码用C99编写并移植到不同的平台。x86-64处理器(Windows和Linux)的构建现已发布。内存管理到目前为止,都是在参考计数器的基础上完成的。如果该语言引起人们的兴趣并尝试使用它,则安排一个更高级的垃圾收集器将是有意义的。该语言支持放置在堆栈上的经典复合数据类型(数组和结构)以及放置在堆上的动态数组。任何经典的数组或结构也可以通过显式调用放在堆上new()
。Go风格的接口提供了多态性。没有类,对象和继承的概念。多任务它基于“光纤”的概念-简化的流程在同一虚拟机中运行,并且很明显地导致彼此交互。从本质上讲,这是协程的同义词。由于使用这些协程的逻辑略微偏离了Go的传统,并变得更接近Lua和Wren,因此提供代码示例是有意义的:fn childFunc(parent: std.Fiber, buf: ^int) {
for i := 0; i < 5; i++ {
std.println("Child : i=" + std.itoa(i) + " buf=" + std.itoa(buf^))
buf^ = i * 3
fibercall(parent)
}
}
fn parentFunc() {
a := 0
child := fiberspawn(childFunc, &a)
for i := 0; i < 10; i++ {
std.println("Parent: i=" + std.itoa(i) + " buf=" + std.itoa(a))
a = i * 7
if fiberalive(child) {
fibercall(child)
}
}
fiberfree(child)
}
例子
作为展示该语言功能的基本示例,我建议查看基于反向光线跟踪的三维场景渲染程序。它是非常有机地使用的递归,接口,动态数组;多一点人工-多任务处理。将Umka转换程序嵌入C项目的一个示例是转换程序本身的可执行包装的源代码。还有一个示例性的Umka语言扩展,带有C中的外部功能。