• 请不要在回答技术问题时复制粘贴 AI 生成的内容
inshua
V2EX  ›  程序员

发布新语言 ago,鼓吹新思维,邀请贡献者:函数即类,调用帧即其实例

  •  
  •   inshua · 8 days ago · 1218 views

    https://siphonlab.github.io/

    2022 年,我在整理动画、协程、流程引擎等技术时,发现它们在本质上都试图对现实世界中的 “动作 (Action)” 进行形式化表达。通过深入思考,我意识到传统编程语言在描述真实世界动作方面存在严重不足,而这一瓶颈的突破点恰在 Call Frame 的概念。我将 CallFrame 从低层机器机制抽象出来,置于面向对象视角中,并发现对象化的 CallFrame 足以充当对动作的完整表征。基于此观察,我进一步提出 “函数即类、CallFrame 即其实例” 的观点,并据此设计了一门全新的面向对象编程语言——ago(取自世界语中的 Action)。编译器和运行时源码分享在 https://github.com/siphonlab/ago/。

    在以图灵机为基础的程序设计框架中,程序可被视作状态之间连续不断的迁移,而负责完成迁移的正是函数调用。理想化的图灵机假设函数调用是无耗时、不可分割的原子求值过程;从数学函数的抽象角度来看,其执行不包含时间维度,因而无需关注计算所需的具体时长——我们不能谈论求 cos(x) tan(x) 的值要花多久,它们是逻辑活动。然而,在实际硬件与现实世界场景中,每一次状态迁移都必然在时间轴上展开:它可能需要等待外部事件、收集信息并对结果进行处理。传统图灵机模型将函数调用视为单一不可中断的过程,导致单一函数无法表达具有持续性、异步且可被外部因素暂停的动作,例如银行转账、员工请假审批或游戏精灵从点 A 平滑移动到点 B 等等。

    从哲学角度看,这种缺陷并不令人惊讶。亚里士多德式运动观把 kinesis 视为临时过渡状态,强调终点而忽略过程;它更关注结果,而非持续展开的动态。而佛教哲学中的 Saṅkhāra 观念则把运动作为第一本体,类似的,怀特海的过程哲学也认为宇宙由相互关联的事件与过程构成,每个过程拥有完整生命周期——从生成、发展到消亡。这种不同的视角启发我们如何看待现实世界中具有时延性的动作。ago 面向对象编程语言在认知框架上仍以柏拉图‑亚里士多德式为主,但也部分承载了过程哲学式的理念。

    基于上述思考,我得出了 函数即类、CallFrame 即实例 的结论,并通过 ago 语言实现了这一思想,为面向对象编程提供了一种新的视角和工具。

    全文见: https://zenodo.org/records/21256260


    欢迎拍砖

    欢迎加入做贡献

    欢迎投钱

    Supplement 1  ·  7 days ago

    文中对图灵机的认知有问题,实际上图灵机虽然在计算模型上相当于lambda演算,但是它是一个有时空结构的机械实现。已经修正为

    传统程序语言中的“函数”概念,主要继承自阿朗佐·丘奇的 Lambda 演算(Lambda Calculus)模型。在 Lambda 模型中,函数被视为纯粹的数学映射与无状态的符号替换规则。从数学抽象的角度来看,其执行本身不包含时间与空间维度——我们无法谈论求 $\cos(x)$ 或 $\tan(x)$ 需要消耗多少时间,它们是纯粹的逻辑映射。现代高级编程语言普遍延续了这一模型,将函数调用视为不可分割的原子求值过程。这种对“执行过程”的抽象隔离,导致单一函数在语法层面难以直接表达具有持续性、异步性、且可被外部中断的现实动作(例如银行转账、审批流程、或游戏精灵从点 A 到点 B 的平滑移动)。

    从哲学角度看,传统语言对 Lambda 模型的偏爱与现实世界建模的冲突并不令人惊讶。亚里士多德式的运动观把 kinesis 视为临时过渡状态,强调终点(结果)而忽略过程;它更关注静态的结项,而非持续展开的动态。相反,佛教哲学中的“行(Saṅkhāra)”则把运动作为第一本体;怀特海的过程哲学(Process Philosophy)也认为宇宙由相互关联的事件与过程构成,每个过程都拥有从生成、发展到消亡的完整生命周期。这种过程视角的差异,深刻地启发了我们如何看待软件世界中具有时延性、过程性的动作。ago 面向对象编程语言在认知框架上仍以柏拉图‑亚里士多德式为主,但也部分承载了过程哲学式的理念。

    如果能将函数的每一次调用过程实体化,转化为一个可访问、可操控、可持久化的具有独立生命周期的对象,表达现实动作的困难将迎刃而解。而在计算机科学中对应函数调用过程的实体就是 Call Frame。我们知道,在面向对象视野,实体总是意味着对象。那么 Call Frame 的类是谁呢?显然就是函数。

    基于上述思考,我得出了 函数即类、CallFrame 即实例 的结论,并通过 ago 语言实现了这一思想,为面向对象编程提供了一种新的视角和工具。

    这种认知里的函数和 Lambda 风格的数学函数有本质不同,其理论根源应当追溯到图灵机(Turing Machine)模型。在图灵之前,他的导师丘奇已经用 \(\lambda \) 演算(Lambda Calculus)证明了判定问题不可解。但丘奇的模型是一套纯粹的、高度抽象的数学函数替换规则。当时数学界(包括哥德尔)对丘奇的λ演算并不完全买账,因为λ演算过于抽象,缺乏直观的“机械感”,人们无法确信它是否完美等价于人类所有的“机械计算行为”。图灵在不知道丘奇研究的情况下,独立发明了图灵机。哥德尔在看到图灵的模型后立刻赞不绝口,认为图灵通过具体的机器结构、具体的物理步骤,彻底说清楚了什么叫“机械步骤”。ago 语言将调用帧对象化,让其成为一个具有驻留性的实体,可以认为是图灵机在面向对象领域的呈现。

    https://zenodo.org/records/21256260 也更新并补充了例子,欢迎访问新版本。

    2 replies    2026-07-10 16:44:54 +08:00
    sora2blue
        1
    sora2blue  
       8 days ago
    不明觉厉。如果把调用栈当成可持久化的对象,那么首先就要面对确定性(幂等性)的问题,比如带宽、端口、套接字、CPU 架构、ABI 、磁盘空间、文件描述符甚至日期时间,这个问题怎么解决的呢?如果不能做到,和直接持久化入参的区别在哪里呢?有没有一个完全用这个语言编译构建的项目可供学习一下呢?
    inshua
        2
    inshua  
    OP
       6 days ago   ❤️ 1
    @sora2blue 抱歉这么久才回。我写了一个博客分享了一点思路 https://www.cnblogs.com/inshua/articles/21303994 ,和你的关注点可能有点相近。“持久化入参”有点类似状态机里的 message ,它不包括函数执行过程中的 pc 寄存器以及内部的变量值,仅仅是一个入口,还是不够究竟。

    目前还没有完整的项目,只做了一个简单的小爬虫 demo 验证可行性。

    你提到的幂等性问题很棒,之前我和小伙伴正好深入讨论过。

    IO 显然不具有保存的可行性,如果要保存 IO ,暂时几种做法:保存描述,下次按描述进行恢复;开一个进程维持 IO ,ago 这边就保存一个 key 。诸如此类,但是最好不要保存。

    纯 ago 函数具有幂等性,因为它的一切都在掌握中,保存点可以做的很完备,事务也有保证。

    native 函数如果要实现幂等就要靠自己努力了,ago 给了 frame id 和 source location 这样的工具用来辅助实现幂等。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   959 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: d3e9c8b8 · 44ms · UTC 20:17 · PVG 04:17 · LAX 13:17 · JFK 16:17
    ♥ Do have faith in what you're doing.