Project Icon

tao

具有多态和代数效应的静态类型函数式语言

Tao是一种静态类型的函数式编程语言,具有多态性、类型类和广义代数效应等特性。它支持和类型、模式匹配、一级函数和柯里化,并提供良好的诊断功能。Tao致力于实现程序完整性和极致优化,同时作为学习工具。该语言采用Hindley-Milner类型推断,支持代数数据类型和类型多态。Tao目前正在开发中,未来计划加入模块系统和LLVM后端等功能。

Tao

您现在可以在浏览器中测试Tao了!

Tao是一种静态类型的函数式编程语言,具有多态性、类型类、广义代数效应、和类型、模式匹配、一等函数、柯里化、良好的诊断功能等多种特性!

Tao特性演示

更多示例程序,请参见...

目标

目前,Tao是一个业余项目,我没有计划将其转变为生产级语言。随着项目的发展,这可能会改变,但现在我更愿意花时间实验新的语言特性。尽管如此,我对语言本身还是有一些目标的:

  • 全面性

    • 所有程序必须明确处理所有输入。没有恐慌、异常等机制。目标是构建一个足够有表现力的类型系统,能够证明广泛程序的全面性。
    • 随着时间的推移,我希望看到该语言发展出对终止分析技术的支持,如Walther递归
  • 极致优化

    • 我一个相当固执且令人讨厌的观点是,静态类型、全面的函数式编程语言的"优化上限"显著高于具有相对较弱类型系统的传统命令式语言。我希望Tao能成为一个实际的例子,让我可以指向它,而不是使用关于不变量的模糊论点。
    • 我特意确保Tao的核心MIR具有非常小的表面积,使其适合各种优化和静态分析。
    • MIR优化器已经执行了相当多的优化,大大减少了生成的字节码指令数量。请参见下面的列表。
  • 学习

    • 我只有高中水平的数学知识。我想用Tao作为测试台,帮助我学习更多关于数学、证明、类型系统、逻辑和计算的知识。
    • 此外,我希望Tao能成为那些想要涉足语言设计、编译器开发或简单的函数式编程的人的有用工具:考虑到一些语言特性的复杂性,代码库相对较小且实用。

特性

  • Hindley-Milner类型推断
  • 有用的错误信息
  • 代数数据类型
    • 和类型
    • 记录类型
    • 泛型数据类型
    • 名义别名(如:data Metres = Real
  • 类型别名
  • 通过泛型实现的类型多态
    • 类约束
    • 关联类型相等约束
    • 任意where子句(包括关联类型相等)
    • 惰性关联项推断(Foo.Bar.Baz.Biz在每一步都惰性推断类!)
    • 类型检查器是图灵完备的(这算是一个特性吗?可能不是...)
    • 变异性在类型和效果参数中都得到正确追踪
  • 模式匹配
    • 解构和绑定
    • ADT模式
    • 列表模式([a, b, c][a, b .. c]等)
    • 算术模式(如:n + k
    • 居住性检查(如:None穷尽覆盖Maybe Never
    • 递归穷尽性检查
    • let进行模式匹配
  • 一等函数
    • 函数支持模式匹配
    • 柯里化
  • 类型类
    • 类型参数
    • 关联类型
    • 运算符通过类型类实现
  • 代数效应
    • 效应对象(独立于函数,不同于某些语言)
    • 流域和传播语法(相当于Haskell的do表示法,或Rust的async/try块)
    • 泛型效应
    • 多态效应(不再需要try_xasync_x函数!)
    • 效应集(即:可以表达具有多个副作用的值)
    • 效应别名
    • 效应处理器(包括有状态处理器,允许用单子IO表达效应驱动的IO)
    • 效应可以由类型和其他效应参数化
  • 内置列表
    • 专用列表构造语法([a, b, c][a, b .. c, d]等)
  • 显式尾调用优化
    • 更好的语法/保证
  • 优化
    • 泛型代码单态化
    • 内联
    • 常量折叠
    • 符号执行
    • 分支交换
    • 死代码删除
    • 居住性分析
    • 穷尽模式展平
    • 未使用函数剪枝
    • 未使用绑定移除
    • 算术重写/简化
    • 恒等分支移除
  • 字节码编译器
  • 字节码虚拟机

当前正在进行

  • 模式穷尽性检查(健全但过于保守)
  • 算术模式(当前仅实现了自然数加法)
  • 类型类
    • 一致性检查器
    • 可见成员语义以放宽孤儿规则
  • MIR优化器
    • 拆箱
    • 递归类型的自动表示更改
      • data Nat = Succ Nat | Zero转换为运行时整数
      • data List A = Cons (A, List A) | Nil转换为向量
  • 代数效应
    • 高阶效应(需要适当的async支持)
    • 效应对象的任意恢复/挂起
    • 效应对象的完全单态化

计划功能

  • 更好的语法(可能对模式匹配使用缩进敏感?)
  • 模块系统(代替import复制/粘贴)
  • LLVM/Cranelift后端

理念

  • 偏好通用解决方案而非特例处理:应该优先考虑灵活和通用的特性,而不是可能在后期产生棘手问题的特定解决方案,这些问题可能需要更多特例解决方案来解决。提供一个较小的通用特性核心比将语言发展成一个不统一的混乱更好。

  • 正确性优先于便利性:如果某些内容存在问题或边缘情况,不要掩盖裂缝。Tao试图强制程序员编写尽可能完善和无bug的程序。溢出很重要。未处理的模式很重要。重叠的类实现很重要

  • 做显而易见的事:当需要在行为上做出选择时,应该选择最常见的正确做法。其他所有情况都应该默认开启lint或报错。

  • 相似概念应有相似语法:列表/记录/数据类型的构造和解构(即模式匹配)应共享相同的语法。函数参数模式和when模式应共享相同的语法。

  • 局部推理:在可能的情况下,程序/函数/表达式的行为应该只通过局部信息就能明显看出。不应有需要查看导入才能理解的奇怪覆盖或行为变化。

  • 表达你的意思:语法确实很重要!程序是为了阅读而设计的,Tao应该鼓励编写能讲述线性故事的程序。如果你需要来回跳转才能理解程序,那就是需要修复的问题。

  • 抽象应保留'核心'语义:许多语言提供复杂的宏系统,允许大规模的元编程。Tao并不反对元编程和抽象,但积极尝试将这些内容保持在表面语法范围内,以提高可读性并最小化意外因素。作为一个很好的补充,拒绝宏使Tao对IDE和静态分析系统更加友好。

有趣的特性

以下是Tao独有或在其他语言中不常见的一些特性选择。

广义代数效应

Tao支持"广义代数效应"。"效应"意味着Tao可以在类型签名中表达函数的副作用(IO、变异、异常、异步等)。"广义"意味着你可以创建和使用自己的效应来表达任何你想要的东西。"代数"意味着Tao允许代码对一个效应(或一组效应)进行泛化。例如,考虑map函数,用于依次对列表的每个元素应用一个函数:

fn map A, B : (A -> B) -> [A] -> [B]
    | _, [] => []
    \ f, [x .. xs] => [f(x) .. map(f, xs)]

map可以这样使用,例如,将列表中的所有元素翻倍:

[1, 2, 3, 4]
    -> map(fn x => x * 2)

# 结果:[2, 4, 6, 8]

大多数语言,如Rust,都有类似的函数。不幸的是,当我们想在映射函数中做一些哪怕是稍微不同于"纯"映射的事情时,它很快就会失效。例如,考虑一个程序,其映射函数可能失败,或需要完成某些异步操作。必须做以下两件事之一:

  • 让函数通过栈展开"静默"退出,就像在C#、C++等语言中那样。
  • 创建一个可以处理失败的函数副本,如Rust中的try_map

值得注意的是,Haskell主要通过单子解决了这个问题:但它们经常很笨重。效应系统和单子有很多相似之处,但前者更努力地使它们与常规控制流更好地集成。

在Tao中,这个问题可以通过让map对一个效应参数进行泛化来解决,如下所示:

fn map A, B, e : (A -> e ~ B) -> [A] -> e ~ [B]
    | _, [] => []
    \ f, [x .. xs] => [f(x)! .. map(f, xs)!]

这里有几处变化。

首先,我们引入了一个效应参数e。其次,类型签名发生了变化:映射函数A -> B现在在其返回类型上附加了e,变成A -> e ~ B。这也出现在函数的最终返回类型e ~ [B]中,表示函数整体的副作用对应于映射函数执行的副作用。

其次,在实现中调用映射函数后出现了!运算符。这是"效应传播"运算符,向编译器表明f的副作用应该被提升到整个函数的签名中。

注意,除此之外,实现保持不变:我们不需要使用任何复杂的机制来处理副作用(就像在Rust风格的try_map中那样),只需要一个额外的运算符。

由于这个变化,map现在可以接受执行任何副作用的映射函数:抛出错误、IO、生成值、变异等等。它还接受执行任意效应组合的函数,或者根本没有副作用的函数(空集仍然是一个有效的效应集!):

# 生成列表中的每个元素,结果是一个生成器
[1, 2, 3, 4]
    -> map(fn x => yield(x)!)!

# 如果列表中任何元素为`0`,则生成一个错误
[1, 2, 3, 4]
    -> map(fn x => if x = 0 then err("不允许零")! else x)!

# 打印列表中的每个元素
[1, 2, 3, 4]
    -> map(fn x => print(x)!)!

这就是代数效应系统的表达能力:我们不再需要担心函数颜色、隐藏的崩溃/异常,或编写多个版本的函数来处理各种不规则的控制流。由于代数效应的泛化性很强,它也可以用于以可组合的方式将接口与实现分离,允许开发者根据需要交换甚至是非常核心的API(如文件系统访问)的实现,而无需复杂和笨拙的回调系统。

在Tao中,效应是种类,就像Rust中的类型、生命周期和常量一样。它们也独立于函数签名表示,作为"效应对象"(你可以把效应对象想象成类似于Future/Promise,但泛化到所有副作用)。因此,可以在广泛的上下文中使用它们。

算术模式

Tao的类型系统旨在完全可靠(即:不可能触发运行时错误,除了"实现"因素如OOM、栈溢出等)。因此,自然数的减法会产生一个有符号整数,而不是自然数。然而,许多算法仍然需要将数字倒数到零!

为了解决这个问题,Tao支持在模式中执行算术运算,并绑定结果。由于编译器直观地理解这些操作,可以静态确定这些操作的可靠性,并保证永远不会发生运行时错误或溢出。看看这个100%可靠的阶乘程序!

fn factorial =
    | 0 => 1
    \ y ~ x + 1 => y * factorial(x)

所有函数都是lambda,并允许模式匹配

除了语法糖(如类型别名)外,Tao只有两个高级构造:值和类型。每个"函数"实际上只是对应于行内lambda的值,而行内lambda语法自然地泛化以允许模式匹配。允许多个模式参数,每个参数对应函数的一个参数。

def five =
    let identity = fn x => x in
    identity(5)

穷尽的模式匹配

Tao要求模式匹配是穷尽的,如果模式没有被处理,将会产生错误。

非常少的分隔符,但空格不是语义的

在Tao中,每个值都是一个表达式。即使是let,在大多数语言中通常是一个语句,在Tao中也是一个表达式。正因如此,Tao不需要分号和代码块。

柯里化和前缀调用

在Tao中,arg->ff(arg)(函数应用)的简写。此外,这种前缀语法可以链式使用,从而形成非常自然的一级管道语法。

my_list
    -> filter(fn x => x % 2 == 0) # 只包含偶数元素
    -> map(fn x => x * x)         # 对元素进行平方
    -> sum                        # 对元素求和

有用且用户友好的错误诊断

这一点通过图片展示会更好。

Tao错误示例

Tao保留了输入代码的有用信息,如每个元素的跨度,从而能够提供丰富的错误信息,引导用户解决程序问题。诊断信息的渲染是通过我的crate Ariadne完成的。

自动调用图生成

Tao编译器还可以自动生成程序的graphviz调用图,帮助你更好地理解程序。以下是examples/calc.tao中的表达式解析器和REPL。调用图会自动忽略工具函数(即带有$[util]属性的函数),这意味着即使是非常复杂的程序也能变得易于理解。

Tao中表达式解析器的调用图

使用方法

命令

编译/运行一个.tao文件

cargo run -- <文件>

运行编译器测试

cargo test

编译/运行标准库

cargo run -- lib/std.tao

编译器参数

  • --opt:指定优化模式(nonefastsize

  • --debug:为编译阶段启用调试输出(tokensasthirmirbytecode

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号