Fig 编程语言

灵活,但不失控

了解更多

/ 核心特性

动态强类型 · 引用值语义 · 一等函数 · 语法干净。用最少的特性解决最多的问题。

动态与静态融合

变量默认动态,可用 : Type 显式锁定类型,也可以用 := 让编译器推断并冻结类型意图。你可以在原型阶段快速迭代,在稳定后逐步加上类型约束,享受静态检查的安全感——就像有副训练轮,随时可以拆掉。

基于引用的值语义

所有值都是不可变对象,变量只是一个"名字"指向一个值。两个变量可以指向同一个对象,修改通过任意引用可见。没有深拷贝的开销,也没有共享可变状态的陷阱——共享即可见,但没有人能破坏你的数据。

面向对象

基于 struct 的轻量 OOP:定义数据,通过接口描述行为,用 impl 实现多态。没有 class 继承的复杂性,没有 this 指针的迷惑。你只需要数据 + 行为契约,剩下的交给编译器。

函数式编程

一等函数 + 闭包 + 箭头语法,让函数式编程像写数学公式一样自然。map、filter、reduce 开箱即用,闭包捕获自由变量没有额外语法负担。想写纯函数?默认就是不可变。

/ 代码示例

感受 Fig 的语法——从 Hello World 到高级特性,每个代码段都附有执行结果。

// Hello, Fig!
import std.io;
func greet(name) => "Hello, " + name + "!";
io.print(greet("Fig")); // → Hello, Fig!
var flexible = 10;
flexible = "hello"; // 动态类型,可以重新赋值不同类型的值
io.print(flexible); // → hello
var fixed := 20; // := 推断并冻结为 Int 类型,不可变
// fixed = "str" ← 编译错误:类型不匹配
var typed: Int = 42; // 显式类型声明
io.print(typed * 2); // → 84
var a := [1, 2, 3];
var b := a; // b 和 a 指向同一个列表(引用语义)
a[0] = 99;
io.print(b); // → [99, 2, 3]
var empty := []; // 空列表,类型未定
empty += 1;
empty += "two";
io.print(empty); // → [1, "two"] 动态列表,混合类型
// 字典类型
var dict := {"name": "Fig", "year": 2026};
io.print(dict["name"]); // → Fig
struct Point {
x: Int;
y: Int;
}
var p1 := new Point{1, 2};
var p2 := new Point{x: 2, y: 3}; // 命名参数
io.print(p1.x); // → 1
interface Drawable { draw() -> String; }
struct Circle { radius: Double; }
impl Drawable for Circle {
draw() => "圆半径: " + radius;
}
var c := new Circle{5.0};
io.print(c.draw()); // → 圆半径: 5.0
// 闭包:捕获外部变量
func multiplier(factor) {
return func (n) => n * factor;
}
var double = multiplier(2);
io.print(double(5)); // → 10
// 高阶函数:map
func map(arr, fn) {
var result := [];
for i in arr {
result += fn(i);
}
return result;
}
io.print(map([1, 2, 3], func (x) => x * x)); // → [1, 4, 9]
// 链式调用风格
var nums := [1, 2, 3, 4, 5];
var evens := nums.filter(func (x) => x % 2 == 0);
io.print(evens); // → [2, 4]

/ 运行路径

从源码到执行 —— Fig 的编译管道全程零 exception、编译速度极快,开发体验流畅。

Lexer 零拷贝词法分析
Parser 自顶向下 + Pratt
Analyzer 语义分析与类型推断
Compiler 字节码生成
VirtualMachine 寄存器虚拟机

整个管道全程不使用 C++ exception,所有错误通过 Result 类型传播。

/ 性能

寄存器虚拟机 · FastCall 优化 · Window Slicing — Fig 在动态语言中达到领先的执行效率。以下为递归计算 fib(30) 的耗时对比,数值越低越好。

测试环境:Intel Core i5-13490F · Windows 11

AOT 编译(仅供参考)
0.05ms
C (clang -O2)
0.06ms
Rust (rustc -O2)
0.08ms
Go (go build)
0.10ms
C# (.NET 9 AOT)
动态语言
28ms
Fig (寄存器 VM)
35ms
Lua 5.4
60ms
Node.js 20
450ms
Python 3.11

Fig 采用寄存器虚拟机架构,避免了传统栈虚拟机频繁的 push/pop 开销。 FastCall 技术通过内联缓存加速函数调用,而 Window Slicing 优化了作用域变量的访问路径。 三项优化合力让 Fig 在动态语言中以约 28ms 完成 fib(30),性能约是 Python 的 16 倍。 AOT 语言的数据仅作为参考基线,Fig 作为动态 VM 语言与其没有直接可比性。

/ 快速上手

1

下载二进制

从 releases 页面下载你操作系统对应的预编译二进制文件(Windows / macOS / Linux 均有提供)。将可执行文件所在目录加入 PATH 环境变量,即可在终端中直接调用 fig 命令。

2

从源码编译

如果你更喜欢从源码构建,确保已安装 xmake 构建系统和 clang 编译器。执行 xmake f --toolchain=clang && xmake 即可编译出 bin/fig 可执行文件。编译通常只需要几秒钟。

3

编写并运行

创建一个 hello.fig 文件,写入 io.print("Hello, World!"),然后在终端输入 fig hello.fig 即可看到输出。Fig 不需要 main 函数——文件顶层的代码就是入口。

/ 项目状态

当前进度与未来规划。已完成前端和核心语义,正在打磨虚拟机和运行时。

前端
核心语义
内置类型
寄存器虚拟机
垃圾回收
标准库(IO/集合/OS)
FFI / C 互操作
LSP / IDE 支持
REPL / 交互式环境
包管理器

/ 社区

贡献代码、报告问题、改进文档——每个开发者都能找到自己的位置。Fig 采用 MIT 许可证,欢迎任何形式的参与。