找回密码
 立即注册
注册 登录
×
热搜: 活动 交友 discuz
查看: 88|回复: 3

设计一种新的系统编程语言

[复制链接]

1

主题

7

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-9-20 14:25:30 | 显示全部楼层 |阅读模式
Go语言的有些方面其实设计的挺好的,能够细粒度的控制内存布局,又有垃圾收集器来避免内存问题。是易用性和性能的很好折中。但是Go的语法很怪异,在"最丑编程语言"的回答里面都被多次提名。而且缺少继承多态、异常处理、泛型(最近可能会有)等关键特性。如果能有一种编程语言,语法和C一致,有指针和GC,能灵活的控制内存布局,能解决内存安全问题,那我一定会用的。可惜没有见到这样的语言,我只能自己来设计了。
指针安全性

有指针以后,第一个安全问题就是野指针问题,也就是长生命期的引用了短生命期。我的解决方案是将指针生命期分为三类。生命期: 堆内存/全局变量>参数/返回值>局部变量。编译器检查规则是:长生命期可以引用短生命期,短生命期不能引用长生命期。
参数和本地生命期情况:
B* foo4(B *b) {
  B b2;
  return &b2; //compile error: 本地生命期 < 参数/返回值生命期
  return b; //ok
}指针有一个heap关键字来表示是在堆上分配的。heap关键字有三个作用:1.表明指针是堆上分配的,2.在堆上分配内存,3.将栈上对象boxing到堆上。鉴于heap关键字这么常用,那么这个编程语言就叫heap语言。
struct A {
  B* b;
}
struct B {
  int i;
}
struct C {
  B b;
}

A a;
void foo1(heap B* b) {
  a.b = b;
}
void foo2(B* b) {
  a.b = heap b;
}
void foo3(B b) {
  a.b = heap b;
}

x := C();
foo1(&x.b) //compile error
foo1(head x.b)
foo2(&x.b)
foo3(x.b)

y := heap C();
foo1(&y.b)
foo2(&y.b)
foo2(y.b)
结构体内部成员的生命期取决于父级的生命期。
继承与多态

我觉得继承和多态是语言抽象能力的重要体现。并且这种抽象没有性能开销。如果信了组合优于继承的话,可以不用这个特性,不是强制的。
和Java一样的单类多接口继承。只有标记为virtual的结构才能有虚方法。
interface I {
  virtual void foo() { ... }
}

virtual struct B {
  int a;
  virtual void bar() { ... }
}

struct A : B, I {
  B* b;
  override void foo(B* b) {
    ...
  }
  override void bar() {...}
}因为有GC,所以不需要RAII,不需要构造函数和析构函数。
指针使用

指针使用点语法调用方法,而不用->
A a;
A* b;
a.foo();
b.foo();指针类型转换
int *a = cast<int*>(p);指针默认不允许运算,除非使用专用函数
int* p;
int *p2 = unsafe_move(p, 1);数组

数组定义和C一致,但是传参数时变成一种胖指针。数组传参时自带长度,并且debug编译模式下运行时检查越界。
int[14] a;
foo(int[] a) {
  print(a.length);
  print(a[0]);
}
foo(a);数组和指针相互转换
int *p;
int[] a = as_array(p, 5);

int *q = a.pointer;异常

众所周知C++中没人使用异常。并不是异常不好,而是异常和手动内存管理不兼容。既然选择了GC,那么异常和GC很搭配。所有可能抛出异常的函数必须使用throws关键字标记。
void foo() throws {
}

void dar() throws {
  foo();
}

void bar2() {
  try {
    foo();
  }
  catch (Exception *e) {
  }
}模板泛型

使用了C++类似的模板来支持泛型。
struct Bar<T> {
  void foo(): T {
    ...
  }
}
null

指针默认不能为null,除非后面有问号
B* a;
B*? a = null;垃圾收集

为什么一定要有GC。手动管理很容易造成内存安全问题。有GC也避免了RAII和析构函数这些机制。GC的开销其实也没有很大,在可接受的范围。
getter/setter

使用操作符重载的方式来定义getter/setter。
struct Bar {
  private int _size;
  setter void size(int s) {
    this._size = s;
  }
}

Bar b;
b.size = 2; // call b.size(2);去掉的特性

并不是特性越多越好,去掉很多C++的特性。

  • 不支持引用,只有指针。
  • 没有class,只有struct。
  • 没有头文件
  • 不支持函数通过参数重载
  • 不支持一次定义多个变量。
  • 不支持RAII
  • 没有构造函数、析构函数(析构函数功能会有其他的替代方案)
  • 不支持嵌套函数、嵌套类、嵌套命名空间等。
  • 没有命名空间(有其他的替代机制)
  • 不支持宏
  • 不支持模板约束,模板元编程。
  • 不支持union类型。
  • 不需要前向声明
  • 没有static的三层意思。
  • 别名定义只能在顶部的import语句中。
  • 可变性是简单的final,没有C++那么复杂的规则。
  • 没有友员机制,默认internal访问级别。
  • 不支持多继承,不支持私有继承
  • ++i和i++只保留一个,并且不返回任何值。
  • 不支持switch语句贯穿
  • 不支持do while, goto语句。

其他

后面还会有闭包和运算符重载等,不再详细写,其他语法参考C++。
基本就是C+OO+GC。没有各种语法糖、没有怪异语法。
最后,heap语言只是开始设计和征求意见,并没有开始开发。
回复

使用道具 举报

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-9-20 14:25:56 | 显示全部楼层
评价一下rust?
回复

使用道具 举报

0

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2022-9-20 14:26:04 | 显示全部楼层
为了安全和性能,牺牲了可读性。不支持继承多态。
回复

使用道具 举报

0

主题

6

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2025-3-17 16:15:18 | 显示全部楼层
嘘,低调。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋| 黑客通

GMT+8, 2025-4-6 04:33 , Processed in 0.090256 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2020, LianLian.

快速回复 返回顶部 返回列表