11 个版本
使用旧的 Rust 2015
0.1.11 | 2018年12月7日 |
---|---|
0.1.10 | 2018年11月26日 |
0.1.8 | 2018年10月25日 |
#1041 in 编程语言
105KB
2K SLoC
Formality
一种通用编程语言,适用于前端应用、后端服务和智能合约。它是
-
快速:没有垃圾回收,最优的 beta-归约和大规模并行 GPU 编译器使其非常快。
-
安全:能够证明其自身程序数学定理的类型系统使其非常安全。
-
简单:整个实现约为 2k 行代码,使其成为简单的标准,您可以自己实现。
定理证明 由于依赖类型,如在其他证明辅助工具中一样是可能的。由于 对称交互演算 (SIC),一种结合了图灵机和 λ-演算最佳特点的新计算模型,因此可以实现大规模并行评估。由于线性,无需垃圾回收:值超出作用域时即可简单地释放。要使用变量两次,我们只需克隆它:SIC 的 懒复制 使其几乎免费。由于不需要所有权系统,我们具有类似 Rust 的计算属性,同时具有类似 Haskell 的高级感觉。
目录
安装
curl -sSf https://static.rust-lang.org/rustup.sh | sh
然后通过克隆存储库来安装它
git clone https://github.com/maiavictor/formality
cd formality
cargo install
使用方法
示例用法
git clone https://github.com/maiavictor/formality
cd examples
# Interpreter evaluation
formality everything.formality.hs -e not_true
# SIC evaluation
formality everything.formality.hs -s -f not_true
# Type-checking
formality everything.formality.hs -t add
formality everything.formality.hs -t add-comm
示例
形式语言非常简单。其程序由两个构建块组成:归纳数据类型,用于表示数据格式;以及函数,用于表示对这些类型数据的计算。这就是你需要的一切。
简单类型
最简单的类型之一,布尔类型,可以声明为
data Bool : Type
| true : Bool
| false : Bool
否定函数可以声明为
let not(b : Bool) =>
case b -> Bool
| true => Bool.false
| false => Bool.true
当我们想要检查数据类型的值时,都会使用模式匹配。
递归类型
最简单的递归类型之一,自然数,可以声明为
data Nat : Type
| succ : (n : Nat) -> Nat
| zero : Nat
一个将其翻倍的功能可以写成
let double(a : Nat) =>
case a -> Nat
| succ(pred) => Nat.succ(Nat.succ(fold(pred)))
| zero => Nat.zero
由于形式语言是全总性的,递归是通过使用fold
关键字来执行的,这个关键字在模式匹配的case中可用。它允许我们将相同的逻辑递归地应用到结构上更小的值。
多态类型
类型可以轻松地参数化
data Pair<A : Type, B : Type> : Type
| new : (x : A, y : B) -> Pair
声明多态函数就像将类型作为参数一样简单
let fst(A : Type, B : Type, pair : Pair<A, B>) =>
case pair -> A
| new(x, y) => x
这允许你为多个具体类型重用同一个函数的实现,这是一个强大而古老的技巧,某些“现代系统语言”竟然无法正确实现。
依赖类型
形式语言允许类型不仅由其他静态类型参数化,还可以由运行时值参数化:我们称之为“索引”。经典的Vector
类型,其长度在编译时是符号已知的,可以声明为
data Vect<A : Type> : (n : Nat) -> Type
| cons : (n : Nat, x : A, xs : Vect(n)) -> Vect(Nat.succ(n))
| nil : Vect(Nat.zero)
当我们对那些类型进行模式匹配时,我们可以指定一个依赖于索引的返回类型
let tail(A : Type, n : Nat, vect : Vect<A>(Nat.succ(n))) =>
case vect -> (n) => Vect<A>(pred(n))
| cons(n, x, xs) => xs
| nil => Vect<A>.nil
这允许我们编写强大的类型安全函数,例如一个不能溢出的向量的索引函数。我们还可以使用self
关键字来引用匹配的结构本身,允许我们表达数学归纳(见示例)。
定理证明
这些功能允许形式语言将定理表达为类型。例如,数学上的等价可以定义为
data Eq<A : Type> : (x : A, y : A) -> Type
| refl : (x : A) -> Eq(x, x)
而证明a == b
意味着b == a
的证明只是
let sym(A : Type, a : A, b : A, e : Eq<A>(a, b)) =>
case e -> (a, b) => Eq<A>(b, a)
| refl(x) => Eq<A>.refl(x)
有了这么高的表现力,形式语言类型可以被视为“规范语言”。例如,我们可以写出“排序列表的类型”、“大于10的质数的类型”,甚至“不能被耗尽的智能合约的类型”。
最优评估
以下形式语言程序
id(1000000000(List<Bool>, map(Bool, Bool, not), list))
翻转一个100位长列表中的每个比特,一亿次。它在0.03s
内打印正确的输出。你可以将其增加到超过宇宙中的星星数量,它仍然会立即输出正确的结果。不,你的计算机并没有进行那么多操作:这是因为形式语言被编译为SIC,这是一种函数程序的最优评估器。这使得它可以利用其他语言无法比拟的疯狂运行时优化,使其通常比几十年的编译器(如GHC)还要快。
更多示例
有关更多示例,请查看/examples
目录。
警告
形式语言仍处于实验阶段。有些功能缺失,代码可能存在错误。请勿将其用于火箭引擎。有关更多信息,请参阅此线程。
依赖项
~1MB