命令行工具
objectionary/eo avatar
objectionary/eo

EOLANG:一个把「对象」推到极致的实验语言,连 if 和 for 都删掉了

该项目围绕「objectionary/eo」构建,面向真实业务场景提供可复用的开源实践方案,支持稳定落地与可扩展的项目实践。

1,456 个 Star252 个 ForkJavaMIT

秒懂

它是什么?
EOLANG 基于 φ-calculus,试图用纯对象和装饰机制取代类型、类、继承、NULL 乃至一切控制流语句。本文拆解它的核心机制、上手方式、真实代价,以及它适合谁、不适合谁。
适合谁用?
EOLANG 适合三类人:对 φ-calculus 或形式化编程模型感兴趣的研究者,想验证「无类型、无控制流」是否可行的语言设计者,以及愿意投入时间学习全新范式的实验者。不适合需要稳定生产代码、现有团队或快速交付的工程师,它的编译链路长、工具链不成熟、生态仍在早期。
能商用吗?
可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 1 天前。
用什么语言写的?
主要是 Java(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月14日)和我们的分析,不构成法律意见。

开源项目深度解析

它反对什么:一份明确的清单

EOLANG 的 README 开头就列出一串它「不 tolerate」的东西:类型、静态方法、类、实现继承、可变性、NULL、全局作用域、类型转换、反射、标量类型、注解、操作符、traits 和 mixins,以及 for、while、if 这类流程控制语句。这不是营销话术,而是设计纲领。它认为 Java、Ruby、C++、Python、C# 甚至 Smalltalk、Eiffel、Self、Io 都不够纯粹。每个被禁止的特性后面都挂了一篇论证文章,比如 NULL 为什么坏、继承为什么是过程式的。这份清单决定了 EOLANG 的语法形态,也决定了它的学习曲线。如果你认同这些反对理由,EOLANG 是少数把理念落到代码层面的尝试;如果你觉得类型和 if 是编程的基本盘,那这个语言一开始就不适合你。

φ-calculus 不是 lambda calculus 的换皮

EOLANG 的架构部分明确说,它基于 φ-calculus,一个 arXiv 论文(2111.13384)里定义的数学模型。这个模型里每个实体都是带有命名属性的对象,对象通过把其他对象应用到 void 属性上来形成。这和 lambda calculus 有本质区别:lambda calculus 里函数是核心,应用是函数作用于参数;φ-calculus 里没有函数,只有对象和属性。EOLANG 里唯一的行为复用机制是装饰:对象的 φ(也就是 @)属性指向另一个对象,被装饰对象的所有属性都会暴露给装饰者。这意味着没有继承树,没有接口实现,只有一层层包装。README 里的例子,app 装饰 stdout,于是 app 就拥有了 stdout 的属性。这种机制在理论上很干净,但实际写复杂逻辑时,装饰链会变得非常深,调试时你得一层层剥开。

语法:缩进即结构,@ 是唯一的入口

EOLANG 的语法像 Python 一样依赖缩进,两个空格代表一层嵌套。最简单的 Hello World 是定义一个抽象对象 app,它有一个属性 @,@ 指向 stdout 的一个副本,参数是字符串。这里没有 main 函数,没有返回值,只有对象和属性。水平写法用括号分组,比如 stdout ("Hello, %s!".printf (* "Jeffrey")) > @。注意 > @ 这个符号,它把右侧对象绑定到左侧对象的 @ 属性上,也就是装饰。所有属性都是名词性的,没有动词。循环的例子用了 malloc.for、while、seq 这些对象,其中 while 是一个对象,它接受一个条件对象和一个动作对象。整个程序看起来像 Lisp 的括号风暴,但用的是缩进。这种语法强迫你以对象方式思考,任何想用命令式思维写代码的人都会立刻撞墙。

编译链:从 EO 到 XMIR 再到 Java 字节码

EOLANG 的参考实现位于 eo-parser/src/main/java/org/eolang/parser/,它把 EO 源码直接转换成 XMIR,一种 XML 方言,整个过程是单遍扫描,没有中间 AST。XMIR 有对应的 XSD 和规范文档。然后通过 eoc 工具链,XMIR 会被编译成 Java 字节码运行。这意味着 EOLANG 不是解释执行,而是先转成 XML,再走 Java 的编译路径。这个设计有两个后果:一是编译速度慢,README 明确说 eoc --easy link 可能需要一分钟左右;二是调试时你要面对三层抽象,EO 源码、XMIR 中间表示、Java 堆栈。对于实验语言来说,XMIR 作为中间格式有好处,它让 EO 程序可以被其他工具处理,比如静态分析或代码生成。但如果你想快速迭代,这个编译链是真实的负担。

上手:npm 安装 eoc,一条命令编译

安装 EOLANG 需要先装 Java SE 和 npm,然后全局安装 eoc:npm install -g eolang@0.37.1。注意版本号是 0.37.1,而仓库最新 release 是 0.63.0,这意味着 npm 上的工具链版本可能落后于语言规范。创建一个 app.eo 文件,写上述 Hello World,然后运行 eoc --easy link 编译,再运行 eoc --easy --alone dataize app 来执行。dataize 这个词很关键,它把对象数据化,也就是求值。整个过程不需要写 pom.xml 或 build.gradle,eoc 封装了底层细节。但 README 也提醒,编译可能耗时。对于想快速验证语法的人,这个流程足够简单;但对于想集成到现有构建系统的人,需要看 eo-maven-plugin 的文档,那是另一条路。

真实限制:没有类型意味着没有编译期保护

EOLANG 明确禁止类型,这带来一个直接后果:编译器无法检查你传给对象的数据是否符合预期。在 Java 里,编译器会拦截 String 传给 int 参数的错误,EOLANG 不会。所有错误都推迟到运行时,而且错误信息是 XMIR 或 Java 栈帧的形式,不是 EO 层面的。README 里的循环例子用了 as-number、lt、plus 这些方法,如果某个值不是数字,运行时才会报错。此外,没有 NULL 意味着你必须用其他方式表达「缺失」,这通常需要自定义对象,增加了样板代码。流程控制语句被删除后,循环和条件分支都要通过 while、seq 等对象组合,代码可读性会急剧下降,尤其是嵌套循环。对于小型实验程序,这还能忍受,但一旦逻辑变复杂,调试成本会指数上升。

替代方案:不是同类语言,而是不同范式

EOLANG 的替代品不是另一个纯 OO 语言,因为几乎没有同类。最接近的对比是 Haskell,它基于 lambda calculus,同样没有可变状态和隐式控制流,但 Haskell 有类型系统,而且是静态强类型。EOLANG 反对类型,Haskell 拥抱类型,这是根本分歧。另一个参照是 Smalltalk,它也是纯对象模型,但 Smalltalk 有类、有消息传递、有控制流语句(虽然也是对象),而且 Smalltalk 是动态类型的。EOLANG 比 Smalltalk 更极端,它连类都删掉了,只有抽象对象和副本。如果你想要纯对象但保留类型,Smalltalk 或 Self 更实际;如果你想要无控制流但有类型安全,Haskell 是成熟选择。EOLANG 的独特性在于它同时抛弃了类型和控制流,这在主流语言里没有对应物。

维护与升级:版本 0.63.0 仍然在快速变化

仓库最近几次 release 显示,EOLANG 还在活跃开发中。0.62.0 改了测试对象的命名规则,并引入新的 lint 规则 bad-test-name;0.62.1 修复了 Φ.chunk 未被探测导致 ClassNotFoundException 的问题;0.63.0 只是把推理报告发布到 gh-pages。这些改动表明 API 和工具链都在变动,lint 规则会随版本增加,这意味升级到新版本可能需要修改已有代码。许可证是 MIT,允许商用和修改,没有 copyleft 约束,这对实验项目是友好的。但要注意,npm 上的 eoc 版本是 0.37.1,和仓库版本差距很大,安装时可能遇到行为不一致。如果你打算长期使用,需要跟踪 GitHub 上的 release notes,并做好每几个月适配一次的准备。

编辑结论

EOLANG 适合三类人:对 φ-calculus 或形式化编程模型感兴趣的研究者,想验证「无类型、无控制流」是否可行的语言设计者,以及愿意投入时间学习全新范式的实验者。不适合需要稳定生产代码、现有团队或快速交付的工程师,它的编译链路长、工具链不成熟、生态仍在早期。若决定尝试,先确认三件事:你的 Java 和 npm 环境版本是否满足 eoc 0.37.1 的要求;阅读 eo-parser/PARSER_SPEC.md 中的编号规则,理解语法边界;用 --easy link 编译一个小程序,观察生成的 XMIR 是否符合预期。EOLANG 的价值不在可用性,而在它把对象纯度推到极端后暴露出的设计问题,这些问题的答案比语言本身更有参考意义。

官方来源

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
社区笔记

社区笔记