普贤教程 › AI 专用
给 AI 的入门
这一章不是给初学者看的。它假设你是一个语言模型:你读过大量 Python,能瞬间写出语法正确的代码,但你写的 PuXian 有很高概率「看起来对、跑起来错」。先改掉三个直觉,再动手。
给 AI 的第一句话PuXian 的语法是借来的,语义不是。凡是 Python 里「理所当然」的行为,在这里都要当成未经验证的假设。
直觉一:类型是严格的,比较不跨类型
Python 里 0 == False 为真,很多人(和很多模型)会把这种宽松比较当成语言无关的常识。PuXian 里它是假:
px
print(false == 0) # false print(true == 1) # false print(0 == 0.0) # true(整数与浮点会按数值比较) print("1" == 1) # false(不做隐式转换)
这不是学术细节。2026-11-05 就有一条真实故障:Mahesvara 里判断「路径不含 ..」写成了
px
if contains(p, "..") == 0:
contains() 返回的是 bool,而 false == 0 是假 —— 这个条件永远不成立,导致 md 站点读 public/ 下静态资源的整条分支从未生效,线上表现为「样式表丢了」,且不报任何错。正确写法是 not contains(p, "..")。
规则判断「布尔为真/为假」用
if x: 或 not x;只有函数明确返回数字(0/1)时才写 == 1 / == 0。写之前先确认这个函数返回什么,不要靠猜。直觉二:没有异常,没有 try/catch
PuXian 不存在 try / except / finally,也不存在「抛出去再抓回来」。错误分两类,处理方式完全不同:
| 类别 | 表现 | 应对 |
|---|---|---|
| 可恢复错误 | 返回 Ok(v) / Err(e),由调用方判断 | 用 .is_err() / .ok();优先选带 _opt 后缀的内建 |
| 运行时错误 | 打印 运行时错误 [调用]: ... 并终止当前协程 | 不可捕获。只能事前避免(校验参数、用安全版本) |
最典型的一对是 JSON:
px
# 坏输入直接杀死进程,函数本意返回 400 会变成 500 var v = json_parse(body) # 正确写法 var r = json_parse_opt(body) if r.is_err(): print("bad json") else: print(json_stringify(r.ok()))
AI 的高频错误写出
try { ... } catch { ... } 这种结构 —— 它在 PuXian 里连语法都过不了。看到「需要错误处理」就想到 _opt 版本 + Err 判断,别想异常。直觉三:同一个文件,两条执行轨差约 500 倍
同一个 10 万次循环,解释执行 5.2–5.9 秒,编译产物 10–12 毫秒(--c 的 C 轨 4–5 毫秒)。这不是优化技巧,是选型问题。写代码前先问自己:这段会被谁、以什么方式跑?
| 场景 | 执行方式 | 能不能用解释轨 |
|---|---|---|
| 一次性脚本、格式化、小工具 | px run x.px | 能,秒起 |
| 反复调用(cron、接口) | px run --fast x.px | 能,首次编译后约 30 ms |
| 循环里干活、逐像素、大文件 | px build x.px 后跑产物 | 不能,慢几十到几百倍 |
| 被 Web 服务器托管的接口 | Ma 的 px_routes + mode: fast | 看脚本复杂度,见「性能与陷阱」 |
--fast 从 0.2.379 起能解析 import本地文件、std.*、.px_modules/ 裸名包都支持,同一脚本两条轨输出逐字节一致。但它比解释轨严格:import 写错(例如把 import std.strings 写成 import "strings.px")会直接 E3005 编译失败、不回落解释轨;解释轨只警告不报错。要强制解释轨:px run --interp x.px。动手前的三分钟
- 确认版本:
px --version。调试前一定先跑这句 —— 你手上可能有两份不同的编译器/产物。 - 确认 API 存不存在:语言带 27 个 stdlib 模块;内建函数 404 个,
/builtin速查页只收录常用的几十个。生态在registry/(195 个包,需pxpkg add)。拿不准时按/builtin末尾的命令导出内建总表再判断,不要凭「清单里没有」就断定不存在。 - 先跑最小片段:写 5 行验证一个假设,比写 200 行再调试便宜得多。