指称语义:把程序翻译成 Python 函数
前两篇用操作语义解释程序。大步语义直接给最终结果,小步语义展示每一步规约。第 2 章还有第三种视角:指称语义(denotational semantics)。 指称语义把程序映射到某个更基础的对象。在本文的小语言里,表达式会变成一个 Python 函数,语句也会变成一个 Python 函数。程序的含义从“机器怎样跑”转到“它等价于哪个函数”。 对 Java 程序员来说,可以先把它理解成: 12Function<Environment, Value> // 表达式的含义Function<Environment, Environment> // 语句的含义 本文继续沿用前面的 AST,用 Python 函数重写这套小语言的含义。 三种语义回答三类问题 同一段程序可以从三种角度解释。 语义 关心的问题 本系列里的实现 大步语义 运行完成后得到什么 递归解释器 小步语义 每一步怎样变化 规约机器 指称语义 程序等价于什么对象 函数翻译器 大步和小步都属于操作语义。它们会描述程序在某种抽象机器上怎样执行。指称语义换成另一...
小步语义:把程序执行拆成一步一步的规约
上一篇写了大步语义。大步语义像一次函数调用:给它程序和环境,它直接返回最终环境。小步语义换了观察角度:程序运行时会经历一串中间配置,每一步只做一个局部变化。 这个视角很适合 Java 程序员理解调试器、解释器、状态机和工作流引擎。断点、单步执行、重试、恢复、超时保护,都依赖“当前程序状态可以被保存,下一步可以被明确计算”。 本文继续使用上一篇的小语言,补上小步语义(small-step semantics)。核心目标很直接:把一个完整程序改写成一台可推进的机器。 程序状态变成机器配置 小步语义关心的是配置之间的变化。 1(statement, environment) -> (next_statement, next_environment) statement 是剩余要执行的程序,environment 是当前变量绑定。每执行一步,语句可能变小,环境也可能变化。 例如: 12(x = 1 + 2, {}) -> (x = 3, {})(x = 3, {}) -> (do-nothing, &...
自己写一个解释器:大步语义与递归求值
上一篇已经把字符串解析成 AST。程序结构稳定以后,下一步是给它一套求值规则。最直接的规则叫大步语义(big-step semantics):给定一个表达式和环境,直接得到最终值;给定一个语句和环境,直接得到新的环境。 大步语义适合写成递归解释器。表达式节点递归求值,语句节点递归改变环境。它不会展示每一个中间状态,只关心完整运行后的结果。 本文会实现一个小语言。它支持数字、布尔值、变量、加法、乘法、小于、赋值、顺序执行、条件分支和 while 循环。 大步语义关心最终关系 大步语义可以先记成两条关系: 12expression + environment => valuestatement + environment => new_environment 表达式会产生值,语句会改变环境。环境是变量名到值的映射。 例如: 1x + 1, {x = 2} => 3 赋值语句会得到一个新环境: 1x = x + 1, {x = 2} => {x = 3} 这套写法和 Java 程序员熟悉的递归下降解...
程序先变成语法树:从字符串到 AST
前一篇用 dataclass 手工创建了一个表达式: 1program = Add(Number(1), Add(Number(2), Number(3))) 这已经能演示解释器的基本形状,但它还绕开了一个关键步骤。真实程序通常从文本开始。读者写下的是 x + (2 + y) + 3,解释器需要先把这段文本变成结构化对象,后面的求值规则才有东西可操作。 本文做这件事:写一个很小的 tokenizer 和 parser,把字符串转成 AST(Abstract Syntax Tree,抽象语法树),再对 AST 求值。 程序文本进入系统后的三步 一段源码进入解释器后,可以先粗略拆成三步: 1source text -> tokens -> AST -> value source text 是原始字符串。tokens 是词法单元列表,比如数字、变量名、加号、括号。AST 是语法结构,表达“谁和谁相加”“括号包住哪一段”。value 是执行结果。 本文只实现一个小语言。它支持整数、变量、加法和括号: 1231 + 2x + 3x + (2 + y) + 3 语法规则也...
刚好够用的 Python:为《计算的本质》准备实验语言
上一篇把《计算的本质》的主线压成了一句话:计算就是用有限规则描述可以机械执行的状态变化过程。从这一篇开始,系列进入代码实验。后面的解释器、自动机、图灵机、lambda 演算、抽象解释都需要一套很小的实验语言。 本文选择 Python。它在这里承担两个角色:一方面,代码足够短,方便把注意力留给计算模型;另一方面,Python 和 Java 的距离刚好合适,读者可以看清哪些部分属于模型本身,哪些部分只是语言样板。 本文按 Python 3.12 写代码。大部分示例在 Python 3.10 及以上也能运行,因为结构化模式匹配从 Python 3.10 开始可用。 只需要一只小工具箱 后续文章不会用到完整 Python 知识。实验语言只需要七件工具。 工具 用途 后续出现位置 Java 对照 dataclass 定义不可变语法节点 AST、图灵机配置、lambda 项 record match 按节点类型分派 解释器、规约器 switch + 模式匹配 函数对象 把规则当值传递 指称语义、lambda 演算 Function<T, R> 闭包 保...
重读《计算的本质》:给 Java 程序员的可计算性入门
《计算的本质》容易读散。它表面上在讲 Ruby、抽象语法树、自动机、lambda 演算、停机问题、类型系统,读起来像一串互不相干的经典概念;主线可以压成一句话: 计算就是用有限的规则,描述一个可以机械执行的状态变化过程。 这句话一旦立住,全书就不再是术语集合。第 2 章讲程序语义,是在回答“规则写成程序以后,它到底是什么意思”。第 3、4、5 章讲自动机,是在回答“状态机器多一点存储以后,能力会怎样增长”。第 6、7 章讲 lambda 演算和通用系统,是在回答“形式极其简单的规则,为什么也能表达通用计算”。第 8、9 章讲不可判定性和抽象解释,是在回答“即使计算模型已经足够强,为什么仍然有些问题不能精确解决”。 这套重读系列不打算复述原书。旧文《计算的本质》已经做过概念地图,这个系列换一种路线:用 Python 重写原书的核心实验,并在每一篇里把概念翻译成 Java 程序员熟悉的工程直觉。 为什么原书会显得难 这本书难在视角切换。数学和 Ruby 都会带来阻力,但它们不是最大障碍。 多数业务开发者习惯从库、框架、API、对象协作去理解程序。一个方法能不能跑,通常看参数、返...
AgentScope 全景实战:设计速读与生产级十二层装配
把 AgentScope 当成"另一个 LangChain"是上手时最常见的误区。AgentScope v1.x 在 2025 年中做过一次实质上不向后兼容的 API 重构——v0.x 的 actor-based 多机分布式被整体删除,新核心改为 async-ReAct 循环 + MsgHub 显式消息广播。它的设计取向与 LangChain / LangGraph 也不同:假设开发者从一个 ReActAgent 开始,逐层往外加东西——先有一个 agent 能跑,再共享 LLM 单例,再装工具,再装 MCP,再往上做多 agent 路由,最后接观测和部署。这种"渐进式装配"的次序不是教学方便,是它的实际工程姿态——每一层都能独立验证、独立失败、独立替换。 本文分两部分。第一部分是设计速读:把 AgentScope v1.x 的范式翻转、ReAct + MsgHub 核心抽象、与 LangGraph / CrewAI / MAF 的对位、A2A + MCP 协议化分布式、Trinity-RFT 训练集成讲清楚——理解了"为什么&q...
MyBatis 内部架构深度解析:从 Mapper 方法到 JDBC 执行链
MyBatis 的内部结构并不复杂,但很容易被看散:SqlSession、MapperProxy、MappedStatement、Executor、StatementHandler、TypeHandler、一级缓存、二级缓存、插件链分别出现在不同包里,单看任何一个类都像是局部技巧。把它们放回完整调用链之后,MyBatis 的设计会变得很清楚: MyBatis 的核心不是“把对象自动映射成表”,而是“把 Java 方法稳定地映射到一条可执行的 SQL 描述,再把执行过程拆成可替换的流水线组件”。 本文以 MyBatis 3.5.19 的官方文档与源码 XRef 为基准,重点讨论 MyBatis 运行时内部架构,不展开 MyBatis-Spring 的事务同步、Spring Boot 自动装配,也不讨论 MyBatis-Plus 等增强框架。 总体架构 MyBatis 可以分成两条主线:构建期主线和执行期主线。 构建期负责把 XML、注解、类型别名、类型处理器、插件、缓存配置等材料编译成一个 Configuration 对象。执行期从 SqlSessionFactory 打开 ...
Harness Engineering:长程 Agent 的工程化底座
微信公众号文章《Harness Engineering:让AI Agent长程运行的秘密武器》抓住了一个很重要的行业拐点:Agent 讨论正在从“模型有多强”转向“系统怎么让模型可靠工作”。这个判断是对的,但如果只把 Harness Engineering 理解成“给 Agent 做记忆和交接班”,还是太窄。 更准确的定义是:Harness Engineering 是围绕模型构建一套可执行的工作环境、状态系统、工具边界、验证机制和反馈循环,让 Agent 能跨越单个上下文窗口,持续推进真实任务,并在失败时留下可恢复的证据。 这不是 Prompt Engineering 的升级版,也不是 Context Engineering 的别名。Prompt 解决一次请求怎么说,Context 解决一次请求里放什么,Harness 解决的是任务生命周期怎么被系统托住。 一、为什么 2026 年突然轮到 Harness OpenAI 在 2026 年 2 月发布的 Harness Engineering 文章里披露了一个内部实验:团队从空 Git 仓库开始,用 Codex 构建并发布一个内部...
Agent 全景指南:从必要性、范式演化到高可用落地
导语 Agent 在过去三年从概念走向生产,但围绕它的讨论一直分散在三个不同的层面:什么是 Agent、Agent 形态如何演化、以及如何把 Agent 真正构建成可用产品。这三个问题彼此独立又互相支撑——不理解定义就难以分辨技术争议,不理解演化就把握不到当前最佳实践,不理解落地就停留在 Demo 阶段。 本文把这三层一次梳理清楚:第 1-2 章解决"是什么、为什么",第 3-4 章解决"演化到了哪里、每个模块发生了什么变化",第 5-6 章解决"实际怎么构建一个高可用 Agent"。 第 1 章 Agent 概念与争议 1.1 Agent 的本义:代理 vs 智能体 Agent 这个词在英文语境下的原义是"代理人",但也带有"代理"的含义。国内学术界、工业界很多翻译为"智能体",强调其"智能化"和"自主决策"能力;另一派则倾向译为"代理",更贴合英文中"代理人做某件事情"的本意。 ...
