跳至主要內容

发明新的编程语言

Alex Sun2023年3月17日奇思妙想大约 8 分钟

如果发明一种新语言,它应该有哪些特征?

注意

本文为鸭梨瞎想,短期内(也可能永远不会)并不会实现此语言,暂时也未命名,仅仅是设想未来语言的一些特征。

1. 目的

设计一种安全、简洁、含糖量高的静态语言,保持极端的优雅和原生性能。

这种语言,简单底层又包含高级别的抽象,极端现代化,适用于下面这些人:

考虑到社区发展,应该选择兼容某种语言的生态(从部署的适配上或语法的可转换上)。

2. 设计哲学

我们希望追寻 Python 的设计哲学,并为此设计一门静态语言。

void test(int b) {
    int a;
    if (b > 3) {
        a = b * 5 - 6;
    } else {
        a = b * b;
    }
    return a % 7;
}

我们发现 a 变量本应该是定值,因为它只会被赋值一次。但是它不能声名为常量,而且还需要犹豫它要不要被初始化。三元表达式可能能缓解这类简单问题,但是三元表达式和 if 语句没有任何区别,而且更难维护。

如果像 Kotlin 一样,这个语句就能产生常量:

fun test(b: Int): Int {
    val a = if (b > 3) b * 5 - 6 else b * b
    return a % 7
}

因此我们提出:

3. 语言基本特性

原生类型:

类型大小 (bit)
char8
uchar8
wchar16
int32
uint32
long64
ulong64
float32
double64

同时也提供带有数字后缀的版本:

类型大小 (bit)
int88
int1616
int3232
int6464
uint88
uint1616
uint3232
uint6464
float3232
float6464

不区分原生类型和包装类型,原生类型可调用包装类型的方法是编译时行为。

其他常见类型:

命名原则:

我们把给变量指定类型称为类型注解,如 a: int = b + 5,我们把 @ 一个函数或者变量称为装饰器。这一点类似于 Python 但不同于 Java,@ 注解将在编译时和运行时都发挥作用,减少或不使用反射。

4. 基本语法

5. 语法详解和示例

if 语句:

if (a == 3) {
    // ...
} else if (b == 5) {
    // ...
} else {
    // ...
}

for 语句的循环变量不需要使用 var 定义,并且不能被手动改变,仅仅在作用域内有效:

// 类似于 for (int i = 1; i < 100; ++i)
for (x in 1 .. 100) {
    // ...
}

// 类似于 for (int i = 1; i < 100; i += 3)
for (x in 1 .. 100 .. 3) {
    // ...
}

while 语句和 do ... while 语句也受到支持,类似于 C 语言。

switch 语句也受到支持,但是不需要写 break 也不需要 case,含糖量极高:

// x: int
switch (x) {
    1 -> {
    }
    2, 3 -> {
    }
}

使用 def 定义一个函数:

def f(x: int) {
    // print 是一个宏,默认情况能打印任何类型,因为对象默认继承了 to_str() 方法
    print(x)
}

使用 class 定义一个类:

class A {
    var _a: int?
    var lateinit b
    var _c: int = 3

    init (x: int) {
        mut b = x
    }
}

init 用于创建初始化构造器,下划线开头的成员变量默认为私有的,除此之外默认为受保护的。

使用 interface 定义一个接口,不提供抽象类,接口和抽象类功能合并。

多态行为使用虚表实现,编译时扩展虚表行为使得语言更加动态(例如用于支持对象的混入和扩展)。

io 提供同步的 I/O 支持,异步工具 aio 提供异步版本的 I/O 支持(考虑到编译体积,如果不导入就不会被编译,同时提供静态库和动态库支持。如果不使用 libuv 来实现也是可能的,提供接口来允许第三方库使用,这种情况下就不需要 import aio 了)。

import aio

async def read_file() {
    async with (
        aio.open("f1.png", aio.R | aio.B) as f1,
        aio.open("f2.txt", aio.R) as f2,
    ) {
        // 同步读取
        r1 = await f1.read(1024)
        r2 = await f2.read(1024)

        // 异步读取
        r3, r4 = await aio.all(r1.read(1024), f2.read(1024))
    }
}

aio.run(read_file())