HHYHHY
学习示例扩展规范
GitHub
访问 GitHub查看源码与提交记录 ↗本站下载源码本站存储 · ZIP 源码包1.7.1 · c5a4532
EN
EN
HHY

HHY LANGUAGE

HHY 语言手册

V1.7.1Flow-first 系统脚本语言 · 中文完整手册hhylang.dev

CONTENTS

目录

  1. 01快速开始指南
  2. 02语言基础指南
  3. 03Flow 与 Stream指南
  4. 04文件与路径指南
  5. 05文本、JSON 与 CSV指南
  6. 06进程与系统指南
  7. 07HTTP指南
  8. 08并发与监听指南
  9. 09模块与错误指南
  10. 10脚本示例指南
  11. 11Web Runtime指南
  12. 12受控并发与原子性指南
  13. 13语法完整参考参考
  14. 14标准库函数索引参考
  15. 15CLI 参考参考
  16. 16扩展系统扩展
  17. 17数据库扩展使用指南扩展
  18. 18HTML 扩展与抓取框架扩展
  19. 19语言与 VM 演进路线图路线图
  20. 20编辑器语言支持工具
  21. 21HHY 语言状态报告 · 2026-09-14语言报告

指南 · 01

快速开始

5 分钟安装 HHY、运行第一个 Flow,并掌握日常开发命令。

1.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

1.2HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

1.3第 1 分钟:一键安装(推荐)

支持 macOS arm64、Linux x86_64 与 Linux arm64。安装器自动识别平台、下载 V1.7.1 发行包和同名 .sha256,校验通过后才安装;默认不需要 sudo。

sh
curl -fsSL https://hhylang.dev/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
hhy --version
默认安装版本目录为 ~/.local/share/hhy/1.7.1,命令入口为 ~/.local/bin/hhy。安装器默认解析 GitHub 最新稳定版;HHY_VERSION 可用于固定或回滚版本,HHY_INSTALL_ROOT 和 HHY_BIN_DIR 可以覆盖位置。

1.4macOS:通过 Homebrew Tap 安装

Apple Silicon Mac 可以使用仓库内的 Formula。显式绑定 Git 仓库 URL,使当前仓库在独立 homebrew-tap 仓库建立前也能作为 Tap 使用。

sh
brew tap hh696-wq/hhy https://github.com/hh696-wq/hhy-vm.git
brew install hhy
hhy --version
当前 Formula 只支持 macOS arm64,并锁定官方发行包及其 SHA-256。Linux 请使用一键安装器或 Release 包。

1.5方式二:直接下载 Release

不需要修改 HHY Runtime 时,直接使用官方 V1.7.1 发行包最快。根据系统和 CPU 选择 darwin-arm64、linux-x86_64 或 linux-arm64;压缩包已包含 HHY 可执行文件、官方示例与数据库扩展、所需的非系统运行库、文档、许可证和构建信息。

打开 HHY GitHub Releases ↗
下载最新稳定版本、对应的 .sha256 文件或汇总 SHA256SUMS。
https://github.com/hh696-wq/hhy-vm/releases

sh
tar -xzf hhy-1.7.1-PLATFORM-ARCH.tar.gz
cd hhy-1.7.1-PLATFORM-ARCH
./bin/hhy --version
./bin/hhy run examples/07-language-basics.hhy
保持 bin/ 与 lib/ 的相对位置不变,否则便携包可能找不到随包运行库。PLATFORM-ARCH 替换为 darwin-arm64、linux-x86_64 或 linux-arm64。

1.6下载后校验与加入 PATH

运行下载内容前,应使用同名 .sha256 或 SHA256SUMS 验证文件完整性。macOS 自带 shasum,Linux 通常使用 sha256sum。

sh
# macOS
shasum -a 256 -c hhy-1.7.1-darwin-arm64.tar.gz.sha256

# Linux
sha256sum -c hhy-1.7.1-linux-x86_64.tar.gz.sha256

# 当前终端加入 PATH(替换成实际绝对路径)
export PATH="/absolute/path/hhy-1.7.1-PLATFORM-ARCH/bin:$PATH"
hhy --version

长期使用时,把 export PATH 行放进 shell 配置文件;或者继续通过发行目录中的 ./bin/hhy 运行,不需要系统级安装。

1.7方式三:从源码构建

需要开发 Runtime、验证最新源码或自定义安装位置时再选择源码构建。HHY V1.7.1 正式支持 macOS arm64、Linux arm64 和 Linux x86_64;需要 C11 编译器、make、libcurl、PCRE2 与 BDWGC。数据库扩展还需要对应的 PostgreSQL libpq 或 MySQL client 开发库。

sh
brew install curl pcre2 bdw-gc jansson openssl@3 zlib
git clone https://github.com/hh696-wq/hhy-vm.git
cd hhy-vm
make
make test
./build/hhy --version
brew 命令只适用于 macOS。Linux 的依赖包名称因发行版而异,完整说明见仓库 INSTALL.md。

1.8安装源码构建结果

sh
make install PREFIX="$(brew --prefix)"
hhy --version

PREFIX 可以换成自定义绝对路径。确认 PREFIX/bin 已在 PATH 后,所有 .hhy 文件都可以通过 hhy run 执行。

1.9第一个脚本

hello.hhy
let language = "HHY"

["Flow", "Pipe", "System"]
    |> stream
    |> map { word -> language + ": " + word }
    |> print
sh
hhy check hello.hhy
hhy run hello.hhy

let 创建绑定;List 字面量保存三个 String;stream 显式转成可逐项处理的 Stream;|> 把左侧值注入下一个函数;map 的闭包逐项生成新 String;print 消费结果。check 先验证词法、语法、作用域、模块与已知标准库调用,不执行副作用。

1.10脚本运行与开发流程

任务命令用途
格式化hhy fmt script.hhy写入 HHY 官方格式
检查格式hhy fmt --check script.hhy在 CI 中检查,不修改文件
检查脚本hhy check script.hhy检查语法、作用域和已知 API
运行脚本hhy run script.hhy执行脚本
传递参数hhy run script.hhy input.csv output.json参数进入只读 args
预览计划hhy run --dry-run script.hhy查看脱敏计划,不执行外部副作用

源码使用 .hhy 后缀。查看完整命令:

sh
hhy --help

指南 · 02

语言基础

变量、值、函数、条件、循环和作用域。

2.1动态类型是什么意思

HHY 的变量声明不写类型,值在运行时携带自己的逻辑类型。动态类型不等于随意转换:条件必须得到 Bool,String 不会自动变成 Number、Bool 或 Path,参数数量和不支持的运算都会产生结构化错误。用 type(value) 查看类型,用 is_type(value, name) 判断类型。

hhy
let nothing = null
let enabled = true
let count = 42
let ratio = 0.75
let title = "HHY"
let pattern = /ERROR|WARN/i
let names = ["Ada", "Linus"]
let user = { name: "Ada", active: true }
let indexes = 0..3
let size_limit = 10mib
let timeout_limit = 5s
let completion = 80%

print(type(user))
print(is_type(title, "String"))

2.2标量与单位类型

类型示例用途
Nullnull表示没有值
Booltrue条件与谓词
Int42整数计算
Float3.14浮点计算
String"hello"UTF-8 文本
Regex/ERROR/i文本匹配
Bytes10mib文件或内存大小
Duration5s超时与时间间隔
Percent80%比例
DateTimenow()带时区时间
Pathpath("logs")文件系统路径

String、数字、单位和 Path 的精确边界行为属于 Reference。日常脚本只需记住:HHY 不会在 String、Number、Bool 和 Path 之间做隐式转换。

查看类型与语法参考 →
查阅 UTF-8、数值溢出、运算符和字面量的精确定义。
/zh/learn/syntax-reference

2.3List、Map 与 Range

List 使用从 0 开始的索引,越界产生 IndexError。Map 的键只能是 String,保持插入顺序;map.key 与 map["key"] 等价。普通缺失键返回 null,require 用于区分“键缺失”和“键存在但值是 null”。Range a..b 包含 a、不包含 b,并且不会预先分配 List。

hhy
let original = ["Flow", "System"]
let extended = append(original, "Pipe")
let shortened = remove_at(extended, 1)

let config = { retries: 3, label: null }
let updated = put(config, "timeout", 5s)
let selected = pick(updated, ["retries", "timeout"])

print(original)
print(shortened)
print(get(config, "missing"))
print(require(config, "label"))
print(selected)

List 和 Map 不原地修改。append、remove_at、put、remove_key、pick 都返回新集合,所以示例中的 original 和 config 保持不变。List/Map 支持深度相等;Function、Stream 和系统资源对象不支持值相等。

2.4Result、Stream 与系统对象

类型用于
Result显式保存一次操作的成功值或 Error
Stream惰性处理文件、行、进程、响应和事件
Error携带类别、位置和 Flow stage 的失败
Function用户函数与闭包
系统对象File、Process、HttpResponse 等带只读字段的专用值

系统对象不是 Map。需要写入 JSON 时,先用 map 或 pick 选择普通字段。Stream 的惰性和消费规则在 Flow 章节展开。

2.5变量、作用域与不可变性

hhy
let service = "api"
let mut retries = 0
retries = retries + 1

let 创建不可重新赋值的绑定;需要重新赋值时使用 let mut。List 和 Map 的更新函数返回新值,不修改原集合。变量遵循块级词法作用域,并且必须先声明后使用。

闭包可以捕获外层值。parallel worker 使用隔离快照;不要依赖 worker 修改外层可变绑定。传入普通值并返回结果,再在父流中聚合;详见“并发与监听”。

2.6条件、循环与函数

hhy
fn classify(score) {
    if score >= 90 { return "excellent" }
    else if score >= 60 { return "pass" }
    else { return "retry" }
}

let mut total = 0
for score in [98, 72, 55] {
    if score < 60 { continue }
    total = total + score
}

let mut attempts = 0
while attempts < 3 {
    attempts = attempts + 1
}

print(classify(98))
print(total)

支持 if / else if / else、for item in iterable、while、break 和 continue。for 可以遍历 List、Map entries、Range 或 Stream;遍历 Stream 会消费它。函数使用位置参数,参数数量在调用时检查;没有显式 return 时返回 null。

hhy
fn summarize(items) {
    let mut total = 0

    for item in items {
        if item.enabled {
            total = total + item.score
        }
    }

    return total
}

let users = [
    { name: "Ada", enabled: true, score: 98 },
    { name: "Linus", enabled: false, score: 86 }
]

summarize(users) |> print

当前 1.7.1 请在 Flow 尾随闭包位置使用 { item -> expression };多条语句时必须显式写参数并用 return 返回。单参数闭包在明确的 Flow 上下文中可以使用 { it * 2 }。V1.7.1 不支持重载、泛型或默认参数。

指南 · 03

Flow 与 Stream

理解管道传值、惰性流和单次消费语义。

3.1Pipe 如何传值

Pipe 是普通函数调用的组合规则:x |> f 等价于 f(x),x |> f(a) 等价于 f(x, a),x |> obj.f(a) 等价于 obj.f(x, a)。List、Map 和 Range 须显式调用 stream 后再使用流算子。它不会自动把标量变成 Stream、展开嵌套 Stream、访问 it 字段、忽略错误、字符串化值或启动 Shell。

hhy
[1, 2, 3, 4, 5]
    |> stream
    |> map { number -> number * 2 }
    |> where { number -> number > 5 }
    |> take(2)
    |> print

3.2Stream 的生命周期

Stream 是惰性、拉取式、单次消费序列。创建管道只组合 operator;终端开始拉取时,上游才逐项产生数据。生命周期是 open → next* → close,正常结束、take 提前停止、错误和取消都会从下游向上游关闭资源。

阶段发生的事情
创建Source 返回 Stream,但尚未读取数据
组合map、where 等 operator 连接成 Pipeline
消费print、collect、save 等终端开始逐项拉取
关闭完成、提前停止、Error 或取消释放上游资源
Stream 只能消费一次。不要把同一个 Stream 保存后交给两条 Pipeline;需要重复处理时重新创建 Source,或在有限输入上显式 collect。

3.3逐项、过滤与观察算子

hhy
[5, 2, 5, 1, 3]
    |> stream
    |> skip(1)
    |> take(4)
    |> inspect { number -> print("seen", number) }
    |> where { number -> number >= 3 }
    |> map { number -> number * 10 }
    |> distinct
    |> collect
    |> print

map

map(Stream<T>, Function(T -> U)) -> Stream<U>

惰性地对每项调用闭包,一项输入对应一项输出,不自动展开。

where

where(Stream<T>, Function(T -> Bool)) -> Stream<T>

惰性保留闭包返回 true 的项目;闭包必须返回 Bool。

take

take(Stream<T>, Int) -> Stream<T>

惰性保留前 n 项,达到数量后提前关闭上游。

skip

skip(Stream<T>, Int) -> Stream<T>

惰性丢弃前 n 项,然后传递其余项目。

inspect

inspect(Stream<T>, Function(T -> Value)) -> Stream<T>

为每项执行观察闭包,再原样传递项目。

distinct

distinct(Stream<Hashable>) -> Stream<Hashable>

惰性去除重复的可 Hash 标量,并保存已见集合。

3.4map 与 flat_map 的区别

map 的闭包返回什么,下游就收到什么。如果返回 Stream,结果是 Stream<Stream<T>>。flat_map 要求闭包返回 Stream,并把每个子流依次展开成一条 Stream。

hhy
let batches = [[1, 2], [3, 4]]

batches
    |> stream
    |> flat_map { batch -> batch |> stream }
    |> print

3.5Barrier 和终端算子到底做什么

逐项算子只需保存当前项;Barrier 必须先看完或保存大量输入才能产生正确结果。sort_by 要保存全部输入后排序,group_by 要保存每组的全部 values,collect 把全部项组成 List,reduce/count/sum 等终端算子读取到结束才返回标量。它们都受 max_memory、集合大小和运行时间限制。

hhy
let ordered = [5, 1, 3, 2, 4]
    |> stream
    |> sort_by({ order: "asc" }) { number -> number }
    |> collect

let grouped = [
    { team: "core", name: "Ada" },
    { team: "web", name: "Linus" },
    { team: "core", name: "Grace" }
]
    |> stream
    |> group_by { person -> person.team }
    |> collect

print(ordered)
print(grouped)

sort_by

sort_by(Stream<T>, Map, Function(T -> Comparable)) -> Stream<T>

物化有限输入,按闭包 key 和 asc/desc 选项稳定排序。

group_by

group_by(Stream<T>, Function(T -> Hashable)) -> Stream<Group<T>>

物化有限输入并按 Hash key 输出 Group;Group 含 key 与 values。

collect

collect(Stream<T>) -> List<T>

消费有限 Stream 并物化为 List。

reduce

reduce(Stream<T>, U, Function(State<T,U> -> U)) -> U

以 initial 累积 Stream;闭包接收含 acc/item/index 的 state。

count

count(Stream<T>) -> Int

消费 Stream 并返回项目数。

sum

sum(Stream<Number>) -> Number

消费数值 Stream 并求和,遵守 Int 溢出规则。

min

min(Stream<Number>) -> Number | Null

消费数值 Stream,返回最小值或空流的 null。

max

max(Stream<Number>) -> Number | Null

消费数值 Stream,返回最大值或空流的 null。

first

first(Stream<T>) -> T | Null

返回第一项或 null,并提前关闭上游。

last

last(Stream<T>) -> T | Null

消费 Stream 并返回最后一项或 null。

any

any(Stream<T>, Function(T -> Bool)) -> Bool

任一项目满足谓词即返回 true,并短路关闭上游。

all

all(Stream<T>, Function(T -> Bool)) -> Bool

所有项目满足谓词才返回 true;首个 false 时短路。

不要把 watch、every 或没有明确上限的输入直接送入 sort_by、group_by 或 collect。先用 take、时间窗口或其他业务边界把输入限制为有限流,否则 Runtime 会产生 PlanError。

3.6副作用、错误与并发

只有终端或 Action 才会真正消费 Pipeline。print、for_each、save_*、run 和 send 会执行输出、文件、进程或网络操作。普通 Error 默认终止 Pipeline;需要逐项保留失败时使用 attempt,需要替换整条失败上游时使用 on_error。

parallel(n) 使用隔离 worker 并保持输出顺序。并发数量、可发送值和取消语义在“并发与监听”章节展开。

指南 · 04

文件与路径

遍历目录、读取文本并安全写入结果。

4.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

4.2Path 不是 String

所有文件 API 都要求 Path。path(text) 做词法规范化:折叠重复分隔符和 .,消除可以解析的 ..,但不访问文件系统也不解析符号链接。相对 Path 始终基于进程启动目录,不随被 import 的文件位置变化。

hhy
let source = path("./src/../src/main.c")
let target = path_join(source.parent, "runtime.c")

print(source)
print(source.name)
print(source.extension)
print(source.parent)
print(target)

name、extension、parent 是 Path 的只读字段,不是 path_name()、path_extension()、path_parent() 函数。extension 包含前导点,无扩展名时为空字符串;path_join(base, child) 返回组合后的新 Path。

4.3files:遍历、glob 与元数据

hhy
path("./logs")
    |> files("**/*.log")
    |> where { file -> file.size > 1mib }
    |> flat_map { file -> read_lines(file.path) }
    |> where { line -> contains(line, "ERROR") }
    |> save_lines(path("errors.txt"))

files(root, pattern, options?) 返回惰性的 Stream<File | Directory>,不会返回遍历根本身。pattern 支持 *、?、**;默认不跟随目录符号链接,{ follow_symlinks: true } 可开启并自动跳过检测到的目录循环。

字段含义
path完整 Path
name文件或目录名
extension包含前导点的扩展名
sizeBytes 大小
created创建时间;不可可靠取得时为 null
modified修改时间
is_file / is_dir / is_symlink对象种类标记

File 和 Directory 是系统对象,不是 Map。写入 JSON 前,先把需要的字段映射成普通 Map。

4.4读取文本与二进制

read_text

read_text(Path) -> String

完整读取 UTF-8 文件为 String。

read_lines

read_lines(Path) -> Stream<String>

逐行惰性读取 UTF-8 文件并移除行终止符。

read_bytes

read_bytes(Path) -> BytesBuffer

完整读取二进制文件为 BytesBuffer。

文本 API 验证 UTF-8。图片、压缩包等任意二进制使用 read_bytes 和 write_bytes,不要放进 String。

4.5写入、追加与原子保存

hhy
let input = path("notes.txt")
let backup = path("backup-notes.txt")

write_text(input, "first line\n", { overwrite: true })
append_text(input, "second line\n")
copy(input, backup, { overwrite: false })

read_lines(backup)
    |> map { line -> upper(line) }
    |> save_lines(path("backup/upper.txt"), { create_parents: true })

write_text

write_text(Path, String, Map?) -> Path

以原子替换方式写 String,支持 overwrite/create_parents。

append_text

append_text(Path, String) -> Path

把 String 追加到文件末尾。

write_bytes

write_bytes(Path, BytesBuffer, Map?) -> Path

以原子替换方式写 BytesBuffer。

save_text

save_text(String | Stream<String>, Path, Map?) -> Path

把 String 或文本 Stream 边拉取边原子保存。

save_lines

save_lines(Stream<String>, Path, Map?) -> Path

把 String Stream 逐项写入并补 LF,最终原子替换。

write_text、write_bytes、save_text、save_lines 的 options 支持 overwrite(默认 true)和 create_parents(默认 false)。这些 API 通过同目录临时文件加 rename 提交;overwrite: false 使用原子 no-replace,避免先检查后写入的竞态覆盖。

4.6复制、移动、删除与 dry-run

copy

copy(Path, Path, Map?) -> Path

复制文件,支持原子 no-replace;目标父目录须预先存在。

move

move(Path, Path, Map?) -> Path

移动或重命名文件,遵守覆盖选项。

remove

remove(Path) -> Path

删除明确 Path,并返回该 Path。

sh
hhy run --dry-run backup.hhy
hhy run backup.hhy

copy 和 move 的目标父目录须预先存在,当前 1.7.1 不处理它们的 create_parents 选项。示例使用 overwrite: false,重复运行前请改用新的备份文件名。先检查 dry-run 计划,再执行包含复制、移动或删除的脚本。

文件读取、遍历、写入、进程和网络操作都可能被 RuntimeLimits、取消或宿主权限中止。不要依赖 GC 关闭系统资源;Runtime 会在正常完成、错误、return、exit 和 cancel 路径显式清理。

4.7查阅完整 API

路径与文件 API Reference →
查阅全部签名、参数形式和函数锚点。
/zh/learn/standard-library#fn-path

指南 · 05

文本、JSON 与 CSV

处理 UTF-8 文本、正则表达式和结构化数据。

5.1String 与 UTF-8

String 是不可变 UTF-8 字节序列。length 统计 Unicode code point,byte_length 统计编码后的字节;索引返回一个 code point 对应的单字符 String。文本函数返回新值,不修改原 String。

hhy
let line = "  ERROR: timeout  "

line
    |> trim
    |> replace("ERROR", "WARN")
    |> lower
    |> print

trim

trim(String) -> String

移除 String 两端空白。

split

split(String, String) -> List<String>

按分隔文本把 String 分割成 List<String>。

join

join(List<String>, String) -> String

用分隔文本连接 List<String>。

replace

replace(String, String, String) -> String

返回把匹配文本替换后的新 String。

contains

contains(String | List, Value) -> Bool

判断 String 是否含子串,或 List 是否含相等值。

starts_with

starts_with(String, String) -> Bool

判断 String 是否以指定文本开头。

ends_with

ends_with(String, String) -> Bool

判断 String 是否以指定文本结尾。

lower

lower(String) -> String

返回 Unicode 小写转换后的新 String。

upper

upper(String) -> String

返回 Unicode 大写转换后的新 String。

5.2Regex

Regex 字面量写作 /pattern/flags,支持 i(忽略大小写)、m(多行)、s(点匹配换行)和 u。regex_match 只返回是否匹配;regex_captures 返回完整匹配、字节位置、groups 编号捕获与 named 命名捕获,不匹配时返回 null。

V1.7.1 使用 PCRE2 8-bit,并限制 pattern、subject、match、depth、heap 和捕获组数量;超限产生 ResourceLimitError,避免恶意正则耗尽运行时。

5.3JSON 的类型映射与错误

hhy
read_text(path("users.json"))
    |> parse_json
    |> get("users")
    |> stream
    |> where { user -> user.active == true }
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path("active-users.json"))
JSONHHY
objectMap
arrayList
stringString
integerInt
decimalFloat
true / falseBool
nullNull

parse_json 的错误包含行列。encode_json 可以使用 { pretty: true } 输出可读格式。Function、Stream 和系统对象不能直接编码;先选择普通字段。

5.4CSV 是流式 record

parse_csv 接受完整 String 或 Stream<String>,返回 Stream<Map>;encode_csv 接受 Stream<Map>,返回不带行终止符的 Stream<String>。两者不需要加载完整文件。

hhy
read_lines(path("employees.csv"))
    |> parse_csv({ header: true })
    |> where { row -> row.active == "true" }
    |> encode_csv({ header: true })
    |> save_lines(path("active-employees.csv"))

header 控制首行字段名,delimiter 和 quote 必须是单字符。CSV 不做 schema 推断;数字和 Bool 需要显式转换。encode_csv 不附加换行符,与 save_lines 配合写出。

5.5查阅完整 API

文本与结构化数据 API Reference →
查阅文本、Regex、JSON 和 CSV 的完整函数签名。
/zh/learn/standard-library#fn-contains

指南 · 06

进程与系统

运行命令、消费输出并检查系统状态。

6.1run 与 shell 的安全边界

hhy
run(["git", "log", "--oneline"], { timeout: 5s })
    |> stdout_lines
    |> take(10)
    |> print

run(argv, options?) 直接把 List<String> 交给操作系统,不经过 Shell,因此空格、通配符、$、重定向和管道不会被二次解释。只有确实需要 Shell 语法时才使用 shell(command, options?);Checker 会对 shell 给出安全提示。

选项用途
cwd子进程工作目录 Path
env只覆盖子进程环境
stdin传给命令的标准输入文本
timeout命令最长运行时间
max_outputstdout 与 stderr 捕获上限
包含用户输入时优先使用 run。shell 会解释重定向、管道和变量展开,只在明确需要 Shell 语义时使用。

6.2CommandResult

run 与 shell 默认等待结束并返回 CommandResult,而不是把非零退出码自动当作 HHY Error。脚本应读取 exit_code 决定业务成功。

字段内容
exit_code子进程退出码
stdout标准输出 String
stderr标准错误 String
duration命令运行 Duration

非零 exit_code 不会自动变成 HHY Error。脚本需要根据命令约定判断成功。stdout_lines(result) 可把已捕获输出作为行 Stream 继续处理。

6.3进程快照与字段

processes() 返回当前时刻的 Stream<Process> 快照。Process 不是 Map,提供 pid、name、cpu、memory、status、command 只读字段;转 JSON 前必须显式映射成普通 Map。

排序示例使用 sort_by({ order: "desc" });options Map 必须提供,使用 {} 可采用默认选项;order 只能是 asc 或 desc,默认 asc。排序是稳定 barrier,会物化有限快照。

6.4args、env、system 与 stdin

值内容
args不含脚本路径的 List<String>
env只读环境变量视图
systemOS、架构、主机、CPU、内存和目录信息
stdin_lines()标准输入行 Stream
hhy
if length(args) != 1 {
    print_error("usage: script.hhy <input>")
    exit(3)
}

let input = path(args[0])

6.5查阅完整 API

进程与系统 API Reference →
查阅 run、shell、processes、stdin_lines 和 every 的完整签名。
/zh/learn/standard-library#fn-run

指南 · 07

HTTP

构建请求,配置超时与重试,并处理响应。

7.1Request → Policy → Send → Response

hhy
http.get("https://example.com/users")
    |> timeout(5s)
    |> retry({ count: 3, backoff: 200ms })
    |> send
    |> response_body
    |> parse_json
    |> print
example.com 与 api.example.com 是占位地址,请替换为实际返回 JSON 的接口。视频第 11 集提供可在本机启动的 API 测试服务。

http.get/post/put/delete(url, options?) 只创建不可变 HttpRequest,不访问网络。timeout(request, duration) 与 retry(request, options) 返回修改策略后的新 Request;send(request) 才产生 network effect 并返回 HttpResponse。这样 dry-run 能完整展示而不执行请求。

7.2请求选项与安全默认值

选项用途
queryURL 查询参数
headers请求 header
body请求内容
proxy代理地址
follow_redirects重定向策略
allow_private_networks设为 false 时在实际连接地址上阻止私网、loopback 与 link-local

TLS 验证默认开启。Authorization 和 Cookie 等敏感 header 会在计划、日志和 Error 中脱敏。响应体受 max_http_body 限制。

7.3超时、重试与幂等性

retry({ count, backoff }) 默认只重试连接错误、timeout、429 和部分 5xx。GET、PUT、DELETE 可以按策略重试;POST 默认不自动重试,避免重复创建或扣款。timeout 和 Ctrl+C 都会取消 libcurl 操作并清理响应资源。

重试不是让失败消失。为每个请求设置 timeout,谨慎评估 POST 幂等性,并让最终错误保留 URL(脱敏)、方法、尝试次数和 Flow stage。

7.4HttpResponse 与响应 body

send 返回内存中的 HttpResponse。使用 response_body 读取 UTF-8 文本,使用 response_bytes 读取二进制;send_to(request, path) 则在 curl 回调中直接写同目录临时文件,成功后原子发布,响应只保留 path 和 size。

hhy
http.get("https://api.example.com/status")
    |> timeout(3s)
    |> send
    |> response_body
    |> parse_json
    |> print

7.5查阅完整 API

HTTP API Reference →
查阅请求构造、timeout、retry、send 和响应读取函数。
/zh/learn/standard-library#fn-http-get

指南 · 08

并发与监听

有界并发处理、取消和文件事件流。

8.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

8.2parallel 是有界并发 map

hhy
let urls = [
    "https://example.com",
    "https://example.org"
]

urls
    |> stream
    |> parallel(2) { url ->
    http.get(url)
        |> timeout(5s)
        |> send
}
    |> print
行为保证
并发上限最多运行 n 个 worker,并受 RuntimeLimits 约束
输出顺序与输入顺序一致
背压输入队列和结果缓冲都有界
错误首个未处理 Error 取消剩余任务
返回值等同并发 map,不自动展开子 Stream

如果闭包返回 Stream,在 parallel 后显式使用 flat_map。dry-run 不创建 worker,但仍会按顺序检查闭包中的 Effect。

8.3Sendable 与隔离

worker 收到输入和闭包捕获值的冻结快照,不共享可变对象。Null、Bool、数字、String、单位、Path,以及字段均可发送的普通 List/Map/系统快照可复制过去。

不要把 Stream、打开的 File handle、请求 body stream 等进程内资源发送给 worker。当前 1.7.1 实测可变绑定捕获按隔离快照执行,不会更新父作用域;不要依赖捕获检查一定拒绝 let mut。HHY V1.7.1 不公开线程、锁或 async/await。

8.4watch 与 FileEvent

hhy
watch(path("./src"))
    |> where { event -> event.kind == "created" or event.kind == "modified" }
    |> debounce(300ms)
    |> for_each { event ->
    print(event.path)
}

watch(path, { recursive? }) 返回无限 Stream<FileEvent>。FileEvent 有 kind、path、old_path、timestamp 只读字段;kind 是 created、modified、removed 或 renamed,old_path 仅 renamed 时存在。不同平台和编辑器可能产生不同事件序列;可先在测试目录创建文件验证监听,再核对修改与重命名行为。

字段内容
kindcreated、modified、removed 或 renamed
path事件目标 Path
old_pathrenamed 的原 Path,其余事件为 null
timestamp事件 DateTime

watch 是无限 Stream。使用 Ctrl+C、timeout 或 cancel 结束监听;递归监听受 max_open_files 限制。底层文件系统可能合并短时间内的重复事件。

8.5debounce 与 every

debounce(window) 使用 leading-edge:某个值或同一 kind + path 的 FileEvent 第一项立即输出,窗口内重复项被合并,并从最后一次重复重新计时;不同事件 key 互不阻塞。

every(duration) 返回无限 tick Stream。若下游还在处理,上游遵守背压,不重叠执行同一个 tick。定时和监听流进入 collect/sort/group 前必须先有 take 或业务窗口。

8.6取消与清理

Ctrl+C、timeout、cancel() 和未处理错误触发同一个根 CancellationToken。watcher、sleep、HTTP、子进程与 worker 定期检查它;取消后关闭队列和句柄、终止子进程,并让 Stream close 从下游传播到上游。

指南 · 09

模块与错误

组织代码,传播结构化错误并可靠清理资源。

9.1导入形式与路径解析

hhy
import { add } from "./math.hhy"

add(20, 22) |> print
写法用途
import "./lib/report.hhy" as report导入本地模块命名空间
import { parse } from "./lib/data.hhy"具名导入
import { validate as check } from "./lib/data.hhy"具名导入并设置别名
import http导入标准库模块

相对路径基于当前源码文件目录。标准库使用裸名称;本地文件显式使用 ./、../ 或绝对 Path。

9.2export、作用域与执行

hhy
export let version = "1.0"

export fn normalize_name(name) {
    return name |> trim |> lower
}

fn internal_helper() {
    return null
}

只有 export 名称对外可见。模块拥有独立顶层作用域,并在首次 import 时执行一次、随后缓存。循环依赖在执行前产生 CheckError。V1.7.1 支持标准库、本地模块,以及通过本地包安装的进程扩展模块。

9.3Error 的字段与类别

所有失败都使用 Error,而不是靠 null 或打印文本表达。Error 提供 kind、code、message、source、stage、cause、stack、context 字段;敏感 header、凭据和完整文件内容不会默认进入 context。

内置类别包括 SyntaxError、CheckError、TypeError、ValueError、IndexError、KeyError、EncodingError、IoError、ProcessError、HttpError、HttpStatusError、TimeoutError、CancelledError、ResourceLimitError 和 PlanError。

9.4try/catch 与重新抛出

hhy
try {
    read_text(path("config.json"))
        |> parse_json
        |> print
} catch err {
    print_error(err)
    exit(1)
}

catch 捕获 try 块传播出的第一个错误。catch 正常结束后脚本继续;无法处理时用 throw(err) 保留错误链重新抛出。未处理错误让脚本以非零状态退出。

9.5Flow 错误与单项 Result

hhy
path("./configs")
    |> files("**/*.json")
    |> map { file -> attempt { read_text(file.path) } }
    |> where { result -> result.ok }
    |> map { result -> result.value }
    |> print

Stream 中未处理的 Error 默认终止整条 Pipeline。attempt 把单次操作转换为 Result,适合批处理中显式保留成功项和失败项。on_error 用于替换整条失败的上游 Stream,不会自动跳过错误项。

9.6资源清理保证

Error、return、exit、timeout、Ctrl+C 和 cancel 都走统一 unwind。Stream close 幂等;原子保存失败会删除临时文件并保留旧文件;子进程、HTTP response、watcher 和 worker 都会响应取消。

指南 · 10

脚本示例

用单个脚本完成一项具体任务,学习日志筛选、接口请求、文件处理与数据转换。

10.1Hello HHY 与 Flow 入门

最小可运行案例:把 List 转成 Stream,依次完成映射和过滤,最后输出结果。对应 examples/00-hello.hhy。

00-hello.hhy
let language = "HHY"

["Flow", "Pipe", "System"]
    |> stream
    |> map { word -> language + ": " + word }
    |> print
$ hhy run examples/00-hello.hhy
HHY: Flow
HHY: Pipe
HHY: System

✓ exit 0 · Flow 管道执行完成

10.2并发提取日志告警

递归扫描大日志文件,使用 4 个 worker 提取 ERROR/WARN 行,并将来源文件写入结果。适合服务器日志归档、故障排查和定时任务。

log-errors.hhy
if length(args) != 2 {
    print_error("usage: hhy run log-errors.hhy <log-dir> <output-file>")
    exit(3)
}

let log_dir = path(args[0])
let output_file = path(args[1])

log_dir
    |> files("**/*.log")
    |> where { file -> file.size > 1mib }
    |> parallel(4) { file ->
    read_lines(file.path)
        |> where { line -> regex_match(line, /ERROR|WARN/) }
        |> map { line -> encode_json(file.path) + ": " + line }
        |> collect
}
    |> flat_map { lines -> lines |> stream }
    |> save_lines(output_file)
    |> on_error { err ->
    print_error(err)
    throw(err)
}
sh
hhy run log-errors.hhy ./logs ./output/errors.txt
$ hhy run log-errors.hhy ./logs ./output/errors.txt && head -3 ./output/errors.txt
logs/api.log: 2026-08-25T09:18:42Z ERROR database timeout after 3000ms
logs/worker.log: 2026-08-25T09:18:44Z WARN retrying job #1842
logs/api.log: 2026-08-25T09:18:47Z ERROR upstream returned 502

✓ exit 0 · 3 条告警已写入 output/errors.txt

10.3从 API 同步活跃用户

请求用户接口,经过超时、重试、JSON 解析和字段裁剪后,只把活跃用户原子写入本地文件。对应 examples/02-active-users.hhy。

active-users.hhy
if length(args) != 2 {
    print_error("usage: hhy run active-users.hhy <url> <output-file>")
    exit(3)
}

http.get(args[0])
    |> timeout(5s)
    |> retry({ count: 3, backoff: 200ms })
    |> send
    |> response_body
    |> parse_json
    |> get("users")
    |> stream
    |> where { user -> user.active == true }
    |> map { user ->
    { id: user.id, name: user.name, email: user.email }
}
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path(args[1]))
    |> on_error { err ->
    print_error(err)
    throw(err)
}
sh
hhy run active-users.hhy https://api.example.com/users active-users.json
$ hhy run active-users.hhy http://127.0.0.1:9000/users active-users.json && cat active-users.json
[
  { "id": 101, "name": "Ada", "email": "ada@example.com" },
  { "id": 108, "name": "Linus", "email": "linus@example.com" }
]

✓ exit 0 · 2 位活跃用户已写入 active-users.json

10.4进程 CPU / 内存监控

每 5 秒读取一次进程快照,找出 CPU 超过 70% 或内存超过 1 GiB 的进程,并按内存倒序输出前 10 个。对应 examples/03-process-monitor.hhy。

03-process-monitor.hhy
every(5s)
    |> for_each { tick ->
    processes
        |> where { process ->
        process.cpu > 70% or process.memory > 1gib
    }
        |> sort_by({ order: "desc" }) { process -> process.memory }
        |> take(10)
        |> map { process ->
        {
            pid: process.pid,
            name: process.name,
            cpu: process.cpu,
            memory: process.memory
        }
    }
        |> print
}
$ hhy run examples/03-process-monitor.hhy
[{ pid: 8421, name: "node", cpu: 82.4%, memory: 1.42 GiB },
 { pid: 9107, name: "hhy",  cpu: 74.1%, memory: 86.3 MiB }]

next sample in 5s… · Ctrl+C 安全退出

10.5批量服务健康检查

并发探测多个服务,统一设置超时与重试;单个接口失败时记录错误,不中断整批巡检。可接入发布检查或 CI。

health-check.hhy
let services = [
    { name: "users", url: "https://api.example.com/users/health" },
    { name: "orders", url: "https://api.example.com/orders/health" },
    { name: "billing", url: "https://api.example.com/billing/health" }
]

services
    |> stream
    |> parallel(3) { service ->
    let response = attempt {
        http.get(service.url)
            |> timeout(3s)
            |> retry({ count: 2, backoff: 100ms })
            |> send
            |> response_body
            |> parse_json
    }

    let mut status = "unreachable"
    let mut error_message = null

    if response.ok {
        status = response.value.status
    } else {
        error_message = response.error.message
    }

    return {
        name: service.name,
        ok: response.ok,
        status: status,
        error: error_message
    }
}
    |> collect
    |> encode_json({ pretty: true })
    |> print
$ hhy run health-check.hhy
[
  { "name": "users",   "ok": true,  "status": "healthy", "error": null },
  { "name": "orders",  "ok": true,  "status": "healthy", "error": null },
  { "name": "billing", "ok": false, "status": "unreachable", "error": "request timed out" }
]

✓ exit 0 · 3 个服务并发完成,单点失败未中断批次

10.6发布质量门禁

在发布前并行执行测试、Lint 和生产构建,生成机器可读报告;任一检查失败就用稳定退出码阻止发布。适合 CI/CD、灰度发布和交付验收。

release-gate.hhy
let checks = [
    { name: "unit-tests", command: ["make", "test"] },
    { name: "lint", command: ["npm", "run", "lint"] },
    { name: "production-build", command: ["npm", "run", "build"] }
]

let report = checks
    |> stream
    |> parallel(3) { check ->
    let result = run(check.command, { timeout: 10min, max_output: 8mib })
    return {
        name: check.name,
        passed: result.exit_code == 0,
        exit_code: result.exit_code,
        output: result.stdout
    }
}
    |> collect

report |> encode_json({ pretty: true }) |> save_text(path("release-gate.json"))

if report |> stream |> any { check -> check.passed == false } {
    print_error("release blocked: one or more checks failed")
    exit(1)
}

print("release gate passed")
$ hhy run release-gate.hhy
unit-tests       PASS  4.28s
lint             PASS  1.14s
production-build PASS  6.72s
release-gate.json written

✓ exit 0 · release gate passed

10.7源码敏感信息审计

并发扫描配置与源码,定位疑似 API Key、密码和私钥内容,汇总成可供安全团队复核的报告。适合提交前检查和合规巡检。

secret-audit.hhy
if length(args) != 2 {
    print_error("usage: hhy run secret-audit.hhy <source-dir> <report-file>")
    exit(3)
}

path(args[0])
    |> files("**/*")
    |> where { file ->
    file.extension == ".env" or
    file.extension == ".yml" or
    file.extension == ".json" or
    file.extension == ".ts"
}
    |> parallel(4) { file ->
    read_lines(file.path)
        |> where { line ->
        regex_match(line, /API_KEY|SECRET|PASSWORD|BEGIN PRIVATE KEY/)
    }
        |> map { line -> encode_json(file.path) + ": " + line }
        |> collect
}
    |> flat_map { matches -> matches |> stream }
    |> save_lines(path(args[1]))
$ hhy run secret-audit.hhy ./services secret-findings.txt
services/billing/.env: PAYMENT_API_KEY=***
services/auth/config.yml: PASSWORD: ***

✓ exit 0 · 2 条疑似敏感信息待复核
示例输出已脱敏。实际落地时应限制报告权限,并在流水线中避免打印秘密原文。

10.8订单与支付自动对账

把订单 CSV 与支付 CSV 合并为一条数据流,按 order_id 分组,找出缺少记录或金额不一致的异常订单。适合每日财务对账。

reconcile.hhy
if length(args) != 3 {
    print_error("usage: hhy run reconcile.hhy <orders.csv> <payments.csv> <report.json>")
    exit(3)
}

[path(args[0]), path(args[1])]
    |> stream
    |> flat_map { input ->
    read_lines(input) |> parse_csv({ header: true })
}
    |> group_by { record -> record.order_id }
    |> where { group ->
    (group.values |> stream |> count) != 2 or
    (group.values |> stream |> map { record -> record.amount } |> distinct |> count) != 1
}
    |> map { group ->
    { order_id: group.key, records: group.values, issue: "missing_or_amount_mismatch" }
}
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path(args[2]))
$ hhy run reconcile.hhy orders.csv payments.csv exceptions.json
orders: 12,480 · payments: 12,472
matched: 12,461
exceptions: 19 → exceptions.json

✓ exit 0 · 对账报告已原子写入

10.9SaaS 多租户用量快照

有界并发拉取各租户用量,统一处理超时和重试;单租户失败被隔离并记录,不影响整份快照生成。适合计费、容量分析和客户成功报表。

tenant-snapshot.hhy
let tenants = [
    { id: "acme", url: "https://api.example.com/acme/usage" },
    { id: "nova", url: "https://api.example.com/nova/usage" },
    { id: "orbit", url: "https://api.example.com/orbit/usage" }
]

tenants
    |> stream
    |> parallel(3) { tenant ->
    let result = attempt {
        http.get(tenant.url)
            |> timeout(5s)
            |> retry({ count: 3, backoff: 200ms })
            |> send
            |> response_body
            |> parse_json
    }

    if result.ok {
        return { tenant: tenant.id, ok: true, usage: result.value, error: null }
    }

    return { tenant: tenant.id, ok: false, usage: null, error: result.error.message }
}
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path("tenant-usage-snapshot.json"))
$ hhy run tenant-snapshot.hhy
acme  ✓ requests=184203 storage_gb=82.4
nova  ✓ requests=99102  storage_gb=41.8
orbit ✗ request timed out

✓ exit 0 · tenant-usage-snapshot.json 包含成功数据与失败原因

10.10大体积素材治理

遍历图片与视频素材,筛选超过 5 MiB 的文件并按体积倒序生成 JSON 清单,帮助内容团队定位需要压缩或迁移的资产。

asset-audit.hhy
if length(args) != 2 {
    print_error("usage: hhy run asset-audit.hhy <asset-dir> <report.json>")
    exit(3)
}

path(args[0])
    |> files("**/*")
    |> where { file ->
    file.is_file and
    (file.extension == ".png" or file.extension == ".jpg" or file.extension == ".mp4")
}
    |> where { file -> file.size > 5mib }
    |> sort_by({ order: "desc" }) { file -> file.size }
    |> map { file ->
    { path: file.path, bytes: file.size, extension: file.extension }
}
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path(args[1]))
$ hhy run asset-audit.hhy ./public asset-report.json
scanned 1,842 assets
large assets: 27
largest: public/video/launch.mp4 · 184.2 MiB

✓ exit 0 · asset-report.json 已生成

10.11监听源码并自动构建

监听 C 代码变化,通过 debounce 合并短时间内的连续保存,再执行 make。构建失败只打印错误,监听任务继续运行。

watch-build.hhy
if length(args) != 1 {
    print_error("usage: hhy run watch-build.hhy <source-dir>")
    exit(3)
}

let source_dir = path(args[0])

watch(source_dir, { recursive: true })
    |> where { event ->
    event.kind != "removed" and
    (event.path.extension == ".c" or event.path.extension == ".h")
}
    |> debounce(300ms)
    |> for_each { event ->
    print("changed:", event.path)

    let result = run(["make"], { timeout: 2min, cwd: system.cwd })

    if result.exit_code != 0 {
        print_error(result.stderr)
    } else {
        print(result.stdout)
    }
}
sh
hhy run watch-build.hhy ./src
$ hhy run watch-build.hhy ./src
watching ./src recursively…
changed: src/runtime/flow.c
cc -std=c11 -O2 -c src/runtime/flow.c
cc build/*.o -lcurl -lpcre2-8 -lgc -o build/hhy
Build complete: build/hhy

✓ watcher remains active · waiting for the next change

10.12从 CSV 生成部门汇总报表

读取员工 CSV,筛选在职人员,按部门统计人数和薪资总额,最后原子写入格式化 JSON。输入列为 name、department、active、salary。

csv-report.hhy
if length(args) != 2 {
    print_error("usage: hhy run csv-report.hhy <input.csv> <output.json>")
    exit(3)
}

read_lines(path(args[0]))
    |> parse_csv({ header: true })
    |> where { employee -> employee.active == "true" }
    |> group_by { employee -> employee.department }
    |> map { group ->
    {
        department: group.key,
        employees: group.values |> stream |> count,
        total_salary: group.values
            |> stream
            |> map { employee -> employee.salary |> to_float }
            |> sum
    }
}
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path(args[1]))
sh
hhy run csv-report.hhy employees.csv department-report.json
$ hhy run csv-report.hhy employees.csv department-report.json && cat department-report.json
[
  { "department": "Engineering", "employees": 12, "total_salary": 2160000 },
  { "department": "Product", "employees": 5, "total_salary": 810000 }
]

✓ exit 0 · department-report.json 已原子写入

10.13大文件备份(支持 dry-run)

先创建备份目录(例如 mkdir -p ./backup),再找出超过 100 MiB 的文件并复制到该目录。先用 dry-run 检查动作计划,确认无误后再真实执行。

backup-large.hhy
if length(args) != 2 {
    print_error("usage: hhy run backup-large.hhy <source-dir> <backup-dir>")
    exit(3)
}

let source_dir = path(args[0])
let backup_dir = path(args[1])

source_dir
    |> files("**/*")
    |> where { file -> file.is_file and file.size > 100mib }
    |> for_each { file ->
    let target = path_join(backup_dir, file.name)
    print("copy", file.path, "->", target)
    copy(file.path, target, { overwrite: false })
}
    |> on_error { err ->
    print_error(err)
    throw(err)
}
sh
hhy run --dry-run backup-large.hhy ./downloads ./backup
hhy run backup-large.hhy ./downloads ./backup
$ hhy run --dry-run backup-large.hhy ./downloads ./backup
copy downloads/archive.tar -> backup/archive.tar
copy downloads/database.dump -> backup/database.dump
[dry-run] copy downloads/archive.tar → backup/archive.tar
[dry-run] copy downloads/database.dump → backup/database.dump

✓ exit 0 · 仅生成计划,没有写入文件
备份脚本默认不覆盖同名文件,并自动创建目标目录;正式执行前仍建议先运行 dry-run。

10.14语言基础综合练习

用一个小型汇总任务串起变量、List、Map、函数、条件、循环、作用域和错误处理。对应 examples/07-language-basics.hhy。

07-language-basics.hhy
fn summarize(items) {
    let mut total = 0

    for item in items {
        if item.enabled {
            total = total + item.score
        }
    }

    return total
}

let users = [
    { name: "Ada", enabled: true, score: 98 },
    { name: "Linus", enabled: false, score: 86 }
]

summarize(users) |> print
$ hhy run examples/07-language-basics.hhy
{
  "count": 2,
  "total": 40,
  "average": 20
}

✓ exit 0 · 汇总结果已生成

指南 · 11

Web Runtime

使用 HHY 构建常驻 JSON API、流式服务与多 Worker 应用。

11.1从一个 API 开始

v1.4.3 完整包含 v1.4.0–v1.4.3 的 Web release train:应用在每个 Worker 中只加载一次,handler 可重复调用,单次异常返回 500 而不会终止后续请求。

hhy
import web

fn hello(request) {
    web.json({ ok: true, name: request.query_params.name })
}

web.app()
    |> web.request_id
    |> web.health
    |> web.metrics
    |> web.gzip
    |> web.get("/hello", hello)
    |> web.listen({ host: "127.0.0.1", port: 8080, workers: 4 })
sh
hhy serve app.hhy
hhy serve --dev app.hhy

11.2v1.4.3 能力边界

层能力
Runtimeopaque C embedding、JSON 边界、AST/Bytecode、十万次重复调用测试
HTTPHTTP/1.1、Router、Query/Header/Cookie、请求体硬上限、稳定 4xx/5xx
应用Middleware、静态文件 ETag、上传、CORS、signed cookie、可信代理、热重载
生产Stream、SSE、Range、多进程 Worker、健康检查、结构化日志、Prometheus metrics
生产部署应位于 Caddy、Nginx 或云负载均衡器之后,由代理终止 TLS/HTTP/2;WebSocket 不属于 v1.4。仅当所有直连客户端都是可信代理时启用 web.trust_proxy。

11.3使用 HHY Web 框架

HHY Web 是构建在 v1.4.3 Web Runtime 之上的独立轻量框架。它借鉴 Flask 的易用 API 和 Go 的显式部署方式,提供应用工厂、五种 HTTP 路由、Middleware、Blueprint、统一 Problem JSON、Bearer 鉴权、上传、Stream 与 SSE 助手,但不复制 Router、Worker 或网络栈。

在 GitHub 查看 HHY Web ↗
公开仓库包含中英文文档、Hello World、完整 JSON API、CLI、单测与真实 HTTP 冒烟测试。
https://github.com/hh696-wq/hhy-web

sh
git clone https://github.com/hh696-wq/hhy-web.git
cd hhy-web
./bin/hhy-web run examples/hello/app.hhy --port 8000 --dev
curl http://127.0.0.1:8000/
app.hhy
import "./lib/hhyweb.hhy" as hhyweb

fn hello(request) {
    return hhyweb.json({
        message: "你好,HHY Web!",
        request_id: request.id
    })
}

hhyweb.minimal()
    |> hhyweb.get("/", hello)
    |> hhyweb.serve({ host: "127.0.0.1", port: 8000, workers: 1 })
HHY Web 当前版本为 0.1.0,要求 HHY Language v1.4.3 或更高版本。直接使用 import web 仍是稳定且受支持的底层方式。

指南 · 12

受控并发与原子性

1.7.1 七个实验接口、所有权、效果限制、事务与取消边界,以及可运行示例。

12.11.7.1 的范围与开启方式

默认生效:长期 Context 环境参与 GC roots;Stream 关闭释放负载引用;任务子进程独立配额失败恢复与清理;portable no-replace 使用独占发布。语言规范保持 1.0,Database 保持 1.0.0。

以下七个 API 是默认关闭的实验能力。HHY 采用同步 Runtime 和进程任务,没有新增协程调度器、async/await、共享内存 STM 或全局原子性。同一 HhyContext 不保证多线程并发调用安全。
sh
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run --engine bytecode atomic-state.hhy
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run --engine ast atomic-state.hhy
hhy contracts --format json

上述变量只对单条命令生效。PowerShell 可先设置 $env:HHY_CONCURRENCY_EXPERIMENTS="1",运行后 Remove-Item Env:HHY_CONCURRENCY_EXPERIMENTS。dry-run 只记录契约,返回 Null,不执行回调,也不验证真实结果。

12.2原子性与一致性保证矩阵

资源域提交与失败边界
AtomicState所属 Runtime 同步发布整个候选值;提交前失败保留旧值不跨 Runtime / Worker 共享
单文件稳定 sidecar 锁内原子替换;发布后持久性可能未知仅协作写者;不覆盖跨文件事务或网络文件系统
数据库服务器 COMMIT;区分回滚与未知提交隔离级别、SQL、约束和幂等共同决定一致性
task_map全部成功后按序返回;失败终止并回收直接任务不回滚子任务已发生的外部效果
普通变量保持既有语义与隔离捕获没有自动升级为原子变量

12.3七个实验接口

atomic_state

atomic_state(data)

创建 Runtime/PID 所有者绑定的状态句柄。

atomic_read

atomic_read(state)

读取不可变快照。

atomic_update

atomic_update(state, callback)

校验纯回调候选值并同步发布;提交前错误保留旧值。

atomic_close

atomic_close(state)

关闭句柄;关闭后访问或再次关闭均失败。

atomic_file_update

atomic_file_update(path, timeout, callback)

锁内读改写已有普通文件;timeout 仅限制等锁时间。

transaction_strict

transaction_strict(config, options?, callback)

SQL 绑定当前 tx;捕获错误仍禁止提交;未知提交需对账。

task_map

task_map(data, parallelism, result_limit, callback)

隔离进程执行,按输入顺序返回 List,限制直接子任务和接收结果。

12.4状态更新与句柄所有权

atomic-state.hhy
let state = atomic_state({left: 0, right: 100})
fn transfer(old) { {left: old.left + 1, right: old.right - 1} }
atomic_update(state, transfer)
print(atomic_read(state))
atomic_close(state)

示例完成后 left 为 1、right 为 99。atomic_update 返回新值,atomic_read 读取不可变快照。数据只允许 Null、Bool、Int、有限 Float、String 和递归 List/Map,深度上限 128。Function、Stream 和句柄不允许进入状态。

AtomicState 绑定 Runtime/PID,不能 JSON 编码、传给任务或跨 Worker 捕获。每次访问检查 owner、PID、closed 和 busy;关闭后再次关闭也报错。提交前错误、取消或配额失败保留旧值,不自动重试。

12.5效果契约与提交状态机

strict_capability 分为 pure、bound_transaction 和 external,白名单以 Runtime contracts 为准。严格回调禁止 I/O、任务、Stream、时钟、随机、import、变量赋值(包括局部 mut)和嵌套严格作用域。数据库回调额外允许绑定当前 tx 的 query/execute。第三方扩展不能自行声明 pure 绕过限制。

text
ACTIVE -> COMMITTING -> COMMITTED
   |           |----> ABORTED
   |           `----> UNKNOWN
   `----> ABORTED
捕获回调错误仍会留下 rollback-only 状态,不能继续提交。Checker 提前拒绝直接闭包内已知违规调用,间接调用由 Runtime 验证;AST/Bytecode 共用提交内核,HIR/MIR 保留效果、异常和取消屏障。这不是全程序纯度证明。

12.6单文件协作更新

atomic-file.hhy
fn increment(text) { encode_json(to_int(text) + 1) }
atomic_file_update(path(args[0]), 3s, increment) |> print
sh
printf '0' > /tmp/hhy-counter.txt
HHY_CONCURRENCY_EXPERIMENTS=1 hhy run atomic-file.hhy /tmp/hhy-counter.txt

文件必须预先存在;回调 String → String。等待锁的 Duration 须大于 0 且不超过 300s,不是回调执行期限。所有写者必须遵守同一路径和 <target>.hhy-lock 协议。拒绝符号链接、多硬链接和 .hhy-lock 目标名;活跃写者期间不要删除锁文件。不保证保留 inode、ACL 或扩展属性。

HHY_PUBLISHED_DURABILITY_UNKNOWN:替换已发布但目录持久性未知;HHY_PUBLISHED_CLEANUP_INCOMPLETE:no-replace 已发布但源清理未完成。不能把这些结果当成“未写入”盲目重试;进程崩溃或提交后资源耗尽也应重新读取业务状态。

12.7受限数据库事务与持久幂等

strict-database.hhy
import database
let cfg = read_text(path(args[0])) |> parse_json
let n = cfg |> transaction_strict { tx ->
    database.execute(tx, "UPDATE counters SET n = n + 1 WHERE id = 1", [])
    return database.query(tx, "SELECT n FROM counters WHERE id = 1", []).rows[0].n
}
print(n)

先安装 Database 1.0.0 扩展,准备已有 counters 表及 id=1、n 为整数的记录,再以数据库配置 JSON 路径作为 args[0] 运行。配置遵循数据库扩展文档;凭据留在本地配置中。options 可设置已有 isolation/read_only。

回调不能使用其他 tx、连接池、流式句柄、手动 commit/savepoint,也不能返回 tx(包括嵌套结果)。MySQL 隐式提交语句被拒绝。服务器存储过程和触发器内部效果仍由服务器配置决定,Runtime 无法证明任意 SQL 无外部效果。

DB_COMMIT_UNKNOWN 不等于已回滚。使用同一事务内的唯一业务请求键与业务修改实现持久幂等,未知提交后按该键查询并对账。没有自动重试中间件,也没有数据库与文件/HTTP 的联合回滚。

数据库安装与配置
Database 独立版本 1.0.0
/zh/learn/database-extension

12.8有界任务、取消与原 parallel

bounded-task.hhy
let results = [1, 2, 3] |> task_map(2, 1mib) { n -> n * 2 }
print(results)

示例按输入顺序得到 [2, 4, 6]。task_map 接收 List 并急切返回 List,使用隔离子进程;parallel 保留已有 Stream 行为。并行度为正整数且受 Runtime 限额约束。结果预算为 1b–256mib,限制累计已接收的序列化结果。

每个子进程另有 RLIMIT_FSIZE;待接收文件总量可能达到并行度 × 结果限额,输入/输出 List 另受内存限额约束。后序任务失败可及时被发现;退出时向全部直接任务发 TERM,共享约 500ms 宽限后必要时 KILL 并回收。这不是实时保证,不保证清理脱离进程树的后代,也不回滚外部效果。

12.9验收证据与仍未承诺的能力

  • 本地 69 个引擎/配置用例;每引擎 10,000 次提交;GC、owner、配额与效果拒绝测试。
  • 80 次竞争文件增量;native/portable no-replace 竞争;MySQL/PostgreSQL 32 请求、8 个幂等键及丢失提交回包对账。
  • 120 秒长稳及 100,000 请求 Web 验收通过;不是 24 小时长稳、真实断电或通用共享内存线性化证明。
  • 四平台 CI 与发行验收通过;Windows 为 MSYS2 工件,不包含 Database 扩展。
  • HHY_BYTECODE_BINDING_CACHE=1 和 HHY_STREAM_SOURCE_FUSION=1 仍独立默认关闭;当前证据不支持默认开启或普遍加速声明。

1.7.1 四平台 CI
f0fec9d · 2026-09-14
https://github.com/hh696-wq/hhy-vm/actions/runs/34805271378

真实数据库验收
MySQL / PostgreSQL
https://github.com/hh696-wq/hhy-vm/actions/runs/34805271372

1.7.1 发行说明与工件
已发布;后续 1.7.x 候选仍按各自门槛推进
https://github.com/hh696-wq/hhy-vm/releases/tag/v1.7.1

12.10离线 Markdown 文档

下载中文指南
与本页内容对应的 Markdown 版本
/docs/CONCURRENCY_GUIDE.zh.md

参考 · 13

语法完整参考

V1.7.1 的词法、字面量、运算符、语句、闭包和模块语法。

13.1源文件与词法

项目规则
文件.hhy、UTF-8、LF 或 CRLF
标识符大小写敏感;ASCII 字母、数字和下划线,不能以数字开头
语句结束换行或可选分号
续行未闭合括号或行首/行尾的 |>
注释# 单行注释;首行允许 shebang
/表达式起点为 Regex,已有左操作数后为除法

13.2字面量与原生单位

hhy
let nothing = null
let flags = [true, false]
let numbers = [42, -10, 0xff, 0b1010, 1.5, 1e6]
let name = "HHY"
let strings = ["hello", "Hello, " + name]
let pattern = /ERROR|WARN/i
let list = [1, 2, 3]
let record = { name: "Tom", age: 20 }
let interval = 1..10
let units = [10mib, 5s, 80%]

Range 包含起点、不包含终点。Bytes 支持 b/kb/mb/gb/kib/mib/gib;Duration 支持 ns/us/ms/s/min/h;紧贴数字的 % 是 Percent。当前 1.7.1 中,字符串里的 {name} 会保留为普通文本;拼接字符串请使用 +,输出其他类型请使用 print 的多个参数。String 支持 \, ", \n, \r, \t, \b, \f, \0 转义。

13.3运算符优先级(高到低)

text
()  []  .
not  -  +
*  /  %
+  -
<  <=  >  >=
==  !=
and
or
??
|>
=

and、or 与 ?? 短路执行;= 只允许给 let mut 绑定赋值;|> 左结合。条件必须是 Bool,不存在把 0、空字符串或 null 自动当作 false 的规则。

13.4声明、控制流、函数与模块

hhy
let name = "HHY"
let mut count = 0
count = count + 1
let enabled = true
let items = ["Flow", "Pipe"]

if enabled { print("yes") } else { print("no") }
for item in items { print(item) }
while count < 3 { count = count + 1 }

fn add(a, b) { return a + b }
let doubled = [1, 2] |> stream |> map { number -> number * 2 } |> collect

try { read_text(path("config.json")) } catch err { print_error(err) }
let result = attempt { read_text(path("config.json")) }

import { add as sum_two } from "./math.hhy"
export fn public_api(value) { return value }
结构形式
调用name(args)
Pipex |> f(a) 等价于 f(x, a)
闭包{ param -> expression }
Map{ key: value }
控制流if、for、while、break、continue、return
模块import、as、export

13.5核心值类型

text
Null Bool Int Float String Regex BytesBuffer
List Map Range Function Error Result Stream
Bytes Duration Percent DateTime Path
File Directory FileEvent Process CommandResult
HttpRequest HttpResponse
HHY 是动态类型语言,但不会进行危险的 String/Number 或 String/Bool 隐式转换。Int 是有符号 64 位整数,Float 是 IEEE 754 double。

参考 · 14

标准库函数索引

运行时 Registry 中全部 128 个 V1.7.1 核心 callable 的签名与用途。

14.1如何阅读签名

本页以 V1.7.1 Runtime 的 Callable Contract Registry 为权威来源,共 128 个核心 callable;扩展动态注册的 callable 在各扩展文档中说明。T/U 表示泛型占位值,? 表示可选参数或可空结果,Map? 表示可选 options Map。所有函数都可普通调用;在管道中,左侧值会注入为第一个参数。

这是完整 callable 清单,不含 args、env、system 等只读特殊值,也不把 File.path、HttpResponse.status 等只读字段误列为函数。

14.2核心值、集合、环境与控制(22)

print

print(Value...) -> Null

把值写到标准输出;传入 Stream 时逐项输出并消费它。

print_error

print_error(Value...) -> Null

把值写到标准错误;适合诊断信息。

exit

exit(Int?) -> Never

立即以给定状态码结束脚本,省略时使用 0,并触发资源清理。

length

length(String | List | Map) -> Int

返回 String 的 code point 数或 List/Map 的元素数;Stream 应使用 count。

byte_length

byte_length(String | BytesBuffer) -> Int

返回 String 的 UTF-8 字节数或 BytesBuffer 大小。

type

type(Value) -> String

返回值的逻辑类型名。

is_type

is_type(Value, String) -> Bool

判断值是否具有指定逻辑类型,返回 Bool。

to_int

to_int(Int | Float | String) -> Int

把 Int/Float/String 显式转换为 Int,失败或溢出产生 ValueError。

to_float

to_float(Int | Float | String) -> Float

把 Int/Float/String 显式转换为 Float,失败产生 ValueError。

get

get(List | Map | Record, Int | String) -> Value | Null

安全读取 List 索引、Map 键或对象字段;缺失返回 null。

require

require(Map, String) -> Value

读取必需 Map 键;键缺失产生 KeyError,存在且为 null 时返回 null。

pick

pick(Map, List<String>) -> Map

返回只保留指定键的新 Map,并保留存在的 null 字段。

put

put(Map, String, Value) -> Map

返回新增或替换一个键的新 Map,不修改原 Map。

remove_key

remove_key(Map, String) -> Map

返回移除指定键的新 Map。

append

append(List<T>, T) -> List<T>

返回末尾增加一个元素的新 List。

remove_at

remove_at(List<T>, Int) -> List<T>

返回移除指定索引的新 List;越界产生 IndexError。

now

now() -> DateTime

返回带时区的当前 DateTime。

datetime.parse

datetime.parse(String, String, String) -> DateTime

按明确的格式和时区解析 DateTime,非法输入产生 ValueError。

require_env

require_env(String) -> String

读取必需环境变量;不存在时产生 KeyError。

sleep

sleep(Duration) -> Null

可取消地等待指定 Duration。

cancel

cancel() -> Never

触发当前执行的根取消令牌并开始统一清理。

throw

throw(Error) -> Never

抛出 Error,并沿调用栈或 Flow 传播。

14.3Flow 与 Stream(25)

map/where/take 等转换保持惰性;collect、count、reduce 等终端操作消费 Stream;sort_by 与 group_by 会在资源上限内物化输入。parallel 使用有界隔离 worker 并保持输出顺序。

stream

stream(List<T> | Map | Range) -> Stream<T>

把 List、Map entries 或 Range 转成惰性单次消费 Stream。

range

range(Int, Int) -> Stream<Int>

创建从 start 到 end(不含 end)的 Int Stream。

map

map(Stream<T>, Function(T -> U)) -> Stream<U>

惰性地对每项调用闭包,一项输入对应一项输出,不自动展开。

flat_map

flat_map(Stream<T>, Function(T -> Stream<U>)) -> Stream<U>

对每项返回一个子 Stream,并惰性地把子流依次展开。

where

where(Stream<T>, Function(T -> Bool)) -> Stream<T>

惰性保留闭包返回 true 的项目;闭包必须返回 Bool。

take

take(Stream<T>, Int) -> Stream<T>

惰性保留前 n 项,达到数量后提前关闭上游。

skip

skip(Stream<T>, Int) -> Stream<T>

惰性丢弃前 n 项,然后传递其余项目。

inspect

inspect(Stream<T>, Function(T -> Value)) -> Stream<T>

为每项执行观察闭包,再原样传递项目。

distinct

distinct(Stream<Hashable>) -> Stream<Hashable>

惰性去除重复的可 Hash 标量,并保存已见集合。

sort_by

sort_by(Stream<T>, Map, Function(T -> Comparable)) -> Stream<T>

物化有限输入,按闭包 key 和 asc/desc 选项稳定排序。

group_by

group_by(Stream<T>, Function(T -> Hashable)) -> Stream<Group<T>>

物化有限输入并按 Hash key 输出 Group;Group 含 key 与 values。

debounce

debounce(Stream<T>, Duration) -> Stream<T>

在指定 Duration 内合并快速连续事件,常用于 watch。

on_error

on_error(Stream<T>, Function(Error -> Stream<T>)) -> Stream<T>

当 Stream 失败时调用闭包,用返回的 Stream 恢复或替换后续输出。

parallel

parallel(Stream<T>, Int, Function(T -> U)) -> Stream<U>

用最多 n 个隔离 worker 并发处理,保序、有界缓冲且 fail-fast。

collect

collect(Stream<T>) -> List<T>

消费有限 Stream 并物化为 List。

count

count(Stream<T>) -> Int

消费 Stream 并返回项目数。

first

first(Stream<T>) -> T | Null

返回第一项或 null,并提前关闭上游。

last

last(Stream<T>) -> T | Null

消费 Stream 并返回最后一项或 null。

min

min(Stream<Number>) -> Number | Null

消费数值 Stream,返回最小值或空流的 null。

max

max(Stream<Number>) -> Number | Null

消费数值 Stream,返回最大值或空流的 null。

sum

sum(Stream<Number>) -> Number

消费数值 Stream 并求和,遵守 Int 溢出规则。

reduce

reduce(Stream<T>, U, Function(State<T,U> -> U)) -> U

以 initial 累积 Stream;闭包接收含 acc/item/index 的 state。

any

any(Stream<T>, Function(T -> Bool)) -> Bool

任一项目满足谓词即返回 true,并短路关闭上游。

all

all(Stream<T>, Function(T -> Bool)) -> Bool

所有项目满足谓词才返回 true;首个 false 时短路。

for_each

for_each(Stream<T>, Function(T -> Value)) -> Null

消费 Stream 并为每项执行闭包,返回 null。

14.4文本、Regex、JSON 与 CSV(18)

contains

contains(String | List, Value) -> Bool

判断 String 是否含子串,或 List 是否含相等值。

upper

upper(String) -> String

返回 Unicode 大写转换后的新 String。

lower

lower(String) -> String

返回 Unicode 小写转换后的新 String。

trim

trim(String) -> String

移除 String 两端空白。

trim_start

trim_start(String) -> String

移除 String 开头空白。

trim_end

trim_end(String) -> String

移除 String 末尾空白。

starts_with

starts_with(String, String) -> Bool

判断 String 是否以指定文本开头。

ends_with

ends_with(String, String) -> Bool

判断 String 是否以指定文本结尾。

replace

replace(String, String, String) -> String

返回把匹配文本替换后的新 String。

split

split(String, String) -> List<String>

按分隔文本把 String 分割成 List<String>。

join

join(List<String>, String) -> String

用分隔文本连接 List<String>。

regex_match

regex_match(String, Regex) -> Bool

判断 PCRE2 Regex 是否匹配 String,受正则资源限制。

regex_captures

regex_captures(String, Regex) -> Map | Null

返回完整匹配、字节位置、编号和命名捕获;不匹配返回 null。

url_resolve

url_resolve(String, String?) -> Map

解析绝对或相对 HTTP(S) URL,移除 fragment、默认端口与点路径,并返回 host、path 和稳定指纹。

parse_json

parse_json(String) -> JsonValue

严格解析 JSON String 为普通 HHY 值,错误包含行列。

encode_json

encode_json(JsonValue, Map?) -> String

把可编码普通值转成 JSON;options 可启用 pretty。

parse_csv

parse_csv(String | Stream<String>, Map?) -> Stream<Map>

把 String 或行 Stream 流式解析成 Stream<Map>。

encode_csv

encode_csv(Stream<Map>, Map?) -> Stream<String>

把 Stream<Map> 流式编码为不含换行符的 CSV record Stream。

14.5路径、文件与监听(15)

read_* 是读取操作;write_text、write_bytes、save_text 和 save_lines 使用同目录临时文件加原子替换;append_text 追加到目标文件。文件系统 action 会被 dry-run 拦截。

path

path(String) -> Path

把 String 词法规范化为 Path,不访问文件系统。

path_join

path_join(Path, String | Path) -> Path

组合 Path 与子路径并返回规范化的新 Path。

files

files(Path, String, Map?) -> Stream<File | Directory>

按 glob 惰性遍历根目录,返回 File/Directory Stream。

read_text

read_text(Path) -> String

完整读取 UTF-8 文件为 String。

read_lines

read_lines(Path) -> Stream<String>

逐行惰性读取 UTF-8 文件并移除行终止符。

read_bytes

read_bytes(Path) -> BytesBuffer

完整读取二进制文件为 BytesBuffer。

write_text

write_text(Path, String, Map?) -> Path

以原子替换方式写 String,支持 overwrite/create_parents。

append_text

append_text(Path, String) -> Path

把 String 追加到文件末尾。

write_bytes

write_bytes(Path, BytesBuffer, Map?) -> Path

以原子替换方式写 BytesBuffer。

save_text

save_text(String | Stream<String>, Path, Map?) -> Path

把 String 或文本 Stream 边拉取边原子保存。

save_lines

save_lines(Stream<String>, Path, Map?) -> Path

把 String Stream 逐项写入并补 LF,最终原子替换。

copy

copy(Path, Path, Map?) -> Path

复制文件,支持原子 no-replace;目标父目录须预先存在。

move

move(Path, Path, Map?) -> Path

移动或重命名文件,遵守覆盖选项。

remove

remove(Path) -> Path

删除明确 Path,并返回该 Path。

watch

watch(Path, Map?) -> Stream<FileEvent>

返回无限 FileEvent Stream,支持 recursive 选项并响应取消。

14.6进程、标准输入与定时(6)

run 直接传递 argv,不经过 Shell;只有 shell 明确采用 Shell 解析。进程启动会受 timeout、输出和进程数限制。

run

run(List<String>, Map?) -> CommandResult

直接执行 argv,不经过 Shell;返回 CommandResult。

shell

shell(String, Map?) -> CommandResult

显式用 Shell 执行 String;仅在需要重定向、管道等 Shell 语义时使用。

stdout_lines

stdout_lines(CommandResult) -> Stream<String>

把 CommandResult.stdout 转为惰性行 Stream。

processes

processes() -> Stream<Process>

获取当前进程快照的 Stream<Process>。

stdin_lines

stdin_lines() -> Stream<String>

惰性读取标准输入行,直到 EOF 或取消。

every

every(Duration) -> Stream<Int>

按指定 Duration 产生无限计时 tick Stream。

14.7HTTP(10)

http.* 只构造不可变请求计划,timeout/retry 修改计划,只有 send 产生网络副作用。response_body 返回 UTF-8 文本,二进制响应使用 response_bytes。

http.get

http.get(String, Map?) -> HttpRequest

构造 GET HttpRequest 计划,不发送网络请求。

http.post

http.post(String, Map?) -> HttpRequest

构造 POST HttpRequest 计划,不发送网络请求。

http.put

http.put(String, Map?) -> HttpRequest

构造 PUT HttpRequest 计划,不发送网络请求。

http.delete

http.delete(String, Map?) -> HttpRequest

构造 DELETE HttpRequest 计划,不发送网络请求。

timeout

timeout(HttpRequest, Duration) -> HttpRequest

返回设置请求超时的新 HttpRequest。

retry

retry(HttpRequest, Map) -> HttpRequest

返回配置重试次数和退避的新 HttpRequest。

send

send(HttpRequest) -> HttpResponse

执行 HttpRequest 网络副作用并返回 HttpResponse。

send_to

send_to(HttpRequest, Path) -> HttpResponse

把 HTTP body 流式写入原子文件,返回包含 path 和 size 的 HttpResponse。

response_body

response_body(HttpResponse) -> String

验证响应状态并把有界 body 解码为 UTF-8 String。

response_bytes

response_bytes(HttpResponse) -> BytesBuffer

验证响应状态并返回有界二进制 BytesBuffer。

14.8Web Runtime(25)

web.* 构建常驻应用、响应、中间件和生产端点;只有 web.listen 绑定网络端口。

web.app

web.app() -> WebApp

创建 Web 应用。

web.get

web.get(WebApp, String, Function) -> WebApp

注册 GET 路由。

web.post

web.post(WebApp, String, Function) -> WebApp

注册 POST 路由。

web.put

web.put(WebApp, String, Function) -> WebApp

注册 PUT 路由。

web.patch

web.patch(WebApp, String, Function) -> WebApp

注册 PATCH 路由。

web.delete

web.delete(WebApp, String, Function) -> WebApp

注册 DELETE 路由。

web.use

web.use(WebApp, Function) -> WebApp

追加可短路的 Middleware。

web.static

web.static(WebApp, String, Path) -> WebApp

挂载安全静态目录。

web.cors

web.cors(WebApp, Map?) -> WebApp

启用 CORS 与 OPTIONS 预检。

web.request_id

web.request_id(WebApp) -> WebApp

启用请求 ID。

web.health

web.health(WebApp, String?) -> WebApp

启用健康检查端点。

web.trust_proxy

web.trust_proxy(WebApp) -> WebApp

信任代理提供的客户端地址。

web.text

web.text(String, Map?) -> WebResponse

创建文本响应。

web.html

web.html(String, Map?) -> WebResponse

创建 HTML 响应。

web.json

web.json(JsonValue, Map?) -> WebResponse

创建 JSON 响应。

web.redirect

web.redirect(String, Map?) -> WebResponse

创建重定向响应。

web.response

web.response(Map) -> WebResponse

从选项 Map 创建响应。

web.multipart

web.multipart(WebRequest, Path?) -> Map

解析受限 multipart 表单和上传。

web.stream

web.stream(Stream, Map?) -> WebResponse

创建背压式流响应。

web.sse

web.sse(Stream<String>) -> WebResponse

创建 Server-Sent Events 响应。

web.sign_cookie

web.sign_cookie(String, String) -> String

用 HMAC 签名 Cookie 值。

web.verify_cookie

web.verify_cookie(String, String) -> String | Null

验证并读取签名 Cookie。

web.metrics

web.metrics(WebApp, String?) -> WebApp

启用 Prometheus 指标端点。

web.gzip

web.gzip(WebApp) -> WebApp

按 Accept-Encoding 启用 gzip。

web.listen

web.listen(WebApp, Map?) -> Null

启动有界 HTTP/1.1 Server。

14.9受控并发(7,实验默认关闭)

atomic_state

atomic_state(data)

创建 Runtime/PID 所有者绑定的状态句柄。(实验,默认关闭)

atomic_read

atomic_read(state)

读取不可变快照。(实验,默认关闭)

atomic_update

atomic_update(state, callback)

校验纯回调候选值并同步发布;提交前错误保留旧值。(实验,默认关闭)

atomic_close

atomic_close(state)

关闭句柄;关闭后访问或再次关闭均失败。(实验,默认关闭)

atomic_file_update

atomic_file_update(path, timeout, callback)

锁内读改写已有普通文件;timeout 仅限制等锁时间。(实验,默认关闭)

transaction_strict

transaction_strict(config, options?, callback)

SQL 绑定当前 tx;捕获错误仍禁止提交;未知提交需对账。(实验,默认关闭)

task_map

task_map(data, parallelism, result_limit, callback)

隔离进程执行,按输入顺序返回 List,限制直接子任务和接收结果。(实验,默认关闭)

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

参考 · 15

CLI 参考

运行、检查、格式化、REPL、dry-run 与性能分析。

15.1HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

15.2版本与发布信息

使用 --version 确认当前二进制版本、项目作者、开源许可证和官方联系方式。源码构建使用 ./build/hhy;发行包或安装到 PATH 后可直接使用 hhy。

HHY · 版本信息 · $ ./build/hhy --version
hhy 1.7.1
© 2026 HHY Language contributors
Author: houhuiyang
License: Apache License 2.0
https://hhylang.dev/
huiyang.hou@qq.com

HHY 1.7.1 的真实命令输出;版本、作者、许可证、官网和联系邮箱由 CLI 直接提供。

如果从正式发行包运行,请在解压目录执行 ./bin/hhy --version;如果已经 make install 或加入 PATH,则执行 hhy --version。

15.3完整命令

sh
hhy script.hhy [args...]
hhy run script.hhy [args...]
hhy run --engine ast|bytecode script.hhy [args...]
hhy repl
hhy check script.hhy...
hhy fmt script.hhy...
hhy fmt --check script.hhy...
hhy ast script.hhy
hhy bytecode script.hhy
hhy bytecode --metrics script.hhy
hhy tokens script.hhy
hhy run --dry-run script.hhy
hhy run --limit max_runtime=30s --limit max_memory=256mib script.hhy
hhy serve app.hhy [args...]
hhy serve --dev app.hhy [args...]
hhy serve --engine ast|bytecode --limit max_memory=256mib app.hhy -- [args...]
hhy profile script.hhy [args...]
hhy profile --engine ast|bytecode script.hhy [args...]
hhy profile --cpu script.hhy
hhy profile --heap --format json --output profile.json script.hhy
hhy check --format json script.hhy...
hhy contracts --format json
hhy install [--yes] [--dry-run] [--upgrade] [--locked] [--offline] [--lockfile FILE] [--cache DIR] [--registry DIR --trust-root FILE] <package-or-path>
hhy lock [--lockfile FILE] --registry DIR --trust-root FILE <package>
hhy fetch --locked [--lockfile FILE] [--cache DIR] --registry DIR --trust-root FILE
hhy rollback <package>
hhy doctor extensions [--lockfile FILE] [--cache DIR]
hhy list
hhy remove <package>
hhy --version
hhy -V
hhy --help
hhy -h
命令用途
hhy contracts --format json导出 callable 契约
hhy install安装扩展或按选项升级
hhy lock解析依赖并写入锁文件
hhy fetch --locked缓存锁定依赖
hhy rollback恢复上一已验证扩展版本
hhy doctor extensions核验锁文件、缓存与安装
hhy list / hhy remove列出或移除扩展
hhy check --format json输出 JSON 诊断
hhy run使用默认 Bytecode 引擎运行脚本并传递 args
hhy run --engine ast|bytecode显式选择 AST 回退或 Bytecode 引擎
hhy serve运行常驻 Web 应用;应用通过 web.listen 配置地址、端口和 Worker
hhy serve --dev监听源码变化并自动重新加载 Web 应用
hhy serve --engine ast|bytecode选择 Web handler 使用的执行引擎
hhy serve --limit NAME=VALUE为 Web Runtime 设置可重复的资源限制
hhy profile分析实际引擎的 CPU 热点、调用次数和托管 Heap 分配
hhy repl启动交互环境
hhy check检查语法和核心语义
hhy fmt写入官方格式
hhy fmt --check只检查格式
hhy ast输出 AST
hhy bytecode编译、验证并反汇编 Bytecode
hhy bytecode --metrics输出 compile/verify/prepare 的缓存准入测量 JSON
hhy tokens输出 Lexer Token
hhy run --dry-run预览脱敏执行计划

hhy script.hhy 是 hhy run script.hhy 的简写。v1.7.1 默认使用 Bytecode;可用 --engine ast 或 HHY_ENGINE=ast 立即回退。脚本参数可能以 - 开头时,在 Runtime 选项后使用 -- 分隔。

15.4serve · 常驻 Web 应用

serve 加载并检查一个 HHY Web 应用,然后保持进程运行。--dev 在源码变化后安全重载;--engine 选择 AST 或 Bytecode;--limit 可重复设置 Runtime 资源上限。host、port、max_body、workers 等 HTTP 参数由应用中的 web.listen 显式配置,额外位置参数通过只读 args 传给应用。

sh
hhy serve app.hhy
hhy serve --dev app.hhy -- 8080
hhy serve --engine bytecode \
  --limit max_memory=256mib \
  --limit max_runtime=30s \
  app.hhy -- 8080 production
选项/参数行为
--dev监测入口及其模块源码,变化后重新加载应用
--engine ast|bytecode显式选择 handler 执行引擎;默认 Bytecode
--limit NAME=VALUE覆盖内存、运行时间、文件、进程、并行度、HTTP Body、正则或递归限制,可重复
--dry-run执行计划但拦截外部副作用;主要用于启动配置检查
--结束 Runtime 选项,后续值原样进入应用 args
serve 不会替应用猜测端口;入口文件必须最终调用 web.listen。生产环境应在 Caddy、Nginx 或云负载均衡器之后运行。

15.5Bytecode 缓存准入证据

v1.7.1 新增只读的 --metrics 输出,用真实 compile+verify 与 execution-plan verify 时间评估缓存是否值得引入。固定五负载、21 次配对冷进程测量中,compile+verify 中位数为 0.004–0.012 ms,仅占冷运行墙钟 0.0078%–0.1341%,没有达到 1 ms 且 20% 的双门槛。

$ hhy bytecode --metrics examples/00-hello.hhy
{"bytecode_format_version":1,"compile_verify_ns":9000,"constants":21,"instructions":40,"schema_version":1,"source_bytes":167,"stream_kernel_version":1,"stream_kernels":1,"tool":"hhy bytecode --metrics","verify_prepare_ns":4000}
因此当前没有进程内或磁盘 Bytecode 缓存,也不接受第三方预编译 Bytecode。未来只有真实性能证据触发评审后,才可实现绑定源码、递归依赖、语言/格式/Kernel 版本、编译 feature、target 与安全策略的完整指纹;命中后仍必须经过 checksum、有界解析、完整 Verifier 和 execution-plan verify。

15.6CPU 与 Heap 性能分析

profile 会真实执行脚本,默认在一次运行中同时收集 CPU 和托管 Heap 数据。报告写入 stderr,因此脚本 stdout 保持不变;命令返回脚本原有退出码。

sh
hhy profile --engine bytecode examples/09-profile-algorithms.hhy -- fibonacci 20
hhy profile --engine ast examples/09-profile-algorithms.hhy -- fibonacci 20
hhy profile --heap --format json --output profile.json examples/09-profile-algorithms.hhy -- fibonacci 20
选项行为
--engine ast|bytecode显式分析 AST 或 Bytecode;默认 bytecode,报告 Summary 显示实际 Engine
--cpu只收集 1ms 进程 CPU 采样和调用次数
--heap只收集累计分配、分配次数、Heap 峰值和 GC 后占用
--format text|json选择人类可读或机器可读报告;默认 text
--output <path>把报告写入文件,而不是 stderr
--limit NAME=VALUE与 run 相同,覆盖 Runtime 资源限制
--dry-run与 run 相同,拦截外部副作用并分析计划执行
$ hhy profile --engine bytecode examples/09-profile-algorithms.hhy -- fibonacci 20
HHY profile: examples/09-profile-algorithms.hhy

Summary
  Engine           bytecode
  Wall time        0.013 s
  CPU time         0.008 s
  CPU utilization  58.8%
  CPU samples      4
  Heap peak        1.8 MiB
  Heap after GC    92.0 KiB
  Allocated        1.7 MiB
  Allocations      33040

CPU hotspots
  CPU%    Samples      Calls  Function
   75.0%        3      21891  fibonacci  examples/09-profile-algorithms.hhy:5:1
   25.0%        1          1  print  examples/09-profile-algorithms.hhy:18:6
    0.0%        0          1  <bytecode-top-level>  examples/09-profile-algorithms.hhy:1:1
    0.0%        0          1  length  examples/09-profile-algorithms.hhy:12:10
    0.0%        0          1  to_int  examples/09-profile-algorithms.hhy:17:19
  Note: fewer than 10 CPU samples; use a larger workload for stable results.

Allocation hotspots
  Bytes          Objects  Function
  1.7 MiB            32856  fibonacci  examples/09-profile-algorithms.hhy:5:1
  11.6 KiB              184  <bytecode-top-level>  examples/09-profile-algorithms.hhy:1:1

fibonacci 6765
HHY 1.7.0 · 2026-09-08 · macOS arm64 · 本地单次实测;CPU 样本少于 10 个,计时和热点占比会波动。使用默认编译配置,未启用可选优化。
CPU 使用进程 CPU 时间采样,文件、HTTP 和进程等待不会被误算成 CPU 热点。运行不足数毫秒的脚本可能样本太少,应增大输入或重复负载。Heap 只统计 HHY 的 Boehm GC 托管内存,不包含扩展子进程或原生库自行管理的内存。

15.7解释器性能架构演进

v1.7.1 默认使用经 Compiler/Verifier 验证的 Bytecode VM。原生 Opcode dispatch、静态槽位、可复用调用帧和低分配 Closure 快路径降低 CPU 开销;AST Interpreter 永久保留为语义 oracle 与显式回退。

v1.7.1 / RUNTIME ARCHITECTURE

从源码到执行

实线:默认路径虚线:可选优化
01编译期验证
Source→AST→Bytecode
Compiler
→Verifier→Bytecode
↓↓

结构化 HIR

默认关闭

AST → 六个优化 pass → Bytecode

每个 pass 后独立验证;尺寸超预算回退直接编译。HHY_COMPILER=ir

整数 MIR 计划

默认关闭

直线整数表达式 → 寄存器 MIR → 验证

两条编译路径均可生成,随 Bytecode 交给 VM。HHY_FEEDBACK_SPECIALIZATION=1
↓已验证 Bytecode / 可选 MIR 计划
02运行时反馈
Bytecode VM
Opcode dispatch · 槽位 · 调用帧
可选特化仅在存在已验证 MIR 计划时
参数类型反馈→每次入口 guard→
通过整数 MIR → 装箱返回
未就绪 / 失配通用 Bytecode 路径
↳
AST Interpreter从 AST 直接执行 · 独立语义 oracle · 显式回退
--engine ast
优化开关与语义保证+

六个 pass:常量折叠、常量传播、复制传播、peephole、不可达代码删除与 DCE。不支持的形态或失配走通用路径;算术失败在原操作处恢复错误语义,不重放副作用,频繁失配停用反馈槽。

HHY_SCALAR_REPLACEMENT=1
另行启用局部 List 标量替换,保留 GC/配额分配预约,不消除物理堆分配。

HIR / MIR 默认关闭。编译期验证与运行时 guard 各自独立;真实负载收益尚未达到默认启用门槛。
v1.7.1 的 run、profile 与脚本简写默认使用 Bytecode;可用 --engine ast 或 HHY_ENGINE=ast 立即回退。profile 的 Engine、<top-level>/<bytecode-top-level> 会明确标记实际路径。

15.8开启 HIR / 整数 MIR

这些是环境变量,不是 hhy 子命令。以下命令用于 macOS/Linux 的 sh、bash、zsh;一次性前缀只影响该条命令。已安装使用 hhy,源码工作区替换为 ./build/hhy。请先保存下面文件。

optimizer-demo.hhy
fn calculate(x) { return x * 2 + 1 }
fn first(x) { return [x + 1, x * 2][0] }
for i in 0..32 {
    calculate(i)
    first(i)
}
print(calculate(20))
print(first(40))
sh
# HIR only
HHY_COMPILER=ir hhy run --engine bytecode optimizer-demo.hhy

# Integer MIR only (direct compiler)
HHY_FEEDBACK_SPECIALIZATION=1 hhy run --engine bytecode optimizer-demo.hhy

# HIR + integer MIR + local List scalar replacement
HHY_COMPILER=ir HHY_FEEDBACK_SPECIALIZATION=1 HHY_SCALAR_REPLACEMENT=1 hhy run --engine bytecode optimizer-demo.hhy
预期输出两行 41。循环用于积累参数反馈;设置开关不代表每个函数都会特化。只支持有界直线整数表达式;捕获、动态调用或其他不支持的形态回退通用路径。HIR 与 MIR 可独立开启,标量替换须同时开启 MIR。
sh
# HIR report goes to stderr
HHY_COMPILER=ir HHY_COMPILER_REPORT=1 hhy bytecode --metrics optimizer-demo.hhy

# Runtime hits and deoptimizations go to profile.json
HHY_COMPILER=ir HHY_FEEDBACK_SPECIALIZATION=1 HHY_SCALAR_REPLACEMENT=1 hhy profile --engine bytecode --heap --format json --output profile.json optimizer-demo.hhy

确认 HIR:stderr 报告 compiler 为 structured-ir,查看 passes、size_fallback。确认 MIR:Bytecode metrics 的 typed_plans 表示已生成计划;profile.json 的 typed_specialization.enabled、sites[].hits 表示开启和实际命中,scalar_reservations 表示标量预约。2026-09-08 本例实测两个函数各 26 hits、List 函数 26 scalar_reservations;计时依机器变化。

sh
# Disable individual HIR passes; HIR remains enabled
HHY_COMPILER=ir HHY_COMPILER_DISABLE=fold,dce hhy run optimizer-demo.hhy

# Disable every HIR pass; HIR remains enabled
HHY_COMPILER=ir HHY_COMPILER_DISABLE=all hhy run optimizer-demo.hhy

# Restore the default compiler and disable MIR/scalar replacement (macOS/Linux)
unset HHY_COMPILER HHY_COMPILER_DISABLE HHY_COMPILER_REPORT HHY_FEEDBACK_SPECIALIZATION HHY_SCALAR_REPLACEMENT
hhy run --engine bytecode optimizer-demo.hhy
HHY_COMPILER_DISABLE=all 只关闭 HIR pass,不关闭 HIR 编译链,也不关闭 MIR。HHY_FEEDBACK_SPECIALIZATION=0、HHY_SCALAR_REPLACEMENT=0 可独立关闭对应 Runtime 优化。--engine ast 用于独立 AST 回退。

Windows PowerShell 使用以下环境变量语法;完成后移除变量恢复默认。

text
$env:HHY_COMPILER="ir"
$env:HHY_FEEDBACK_SPECIALIZATION="1"
$env:HHY_SCALAR_REPLACEMENT="1"
hhy run --engine bytecode optimizer-demo.hhy
Remove-Item Env:HHY_COMPILER, Env:HHY_FEEDBACK_SPECIALIZATION, Env:HHY_SCALAR_REPLACEMENT

15.9Runtime 资源限制

run 的 --limit NAME=VALUE 可以重复出现。大小必须带 b/kb/mb/gb/kib/mib/gib,时间必须带 ns/us/ms/s/min/h,计数值不带单位。

sh
hhy run --limit max_runtime=30s --limit max_memory=256mib script.hhy
限制默认值
max_memory512mib
max_open_files256
max_processes16
max_parallelism16
max_http_body16mib
max_regex_steps1000000
max_recursion256
max_runtime0(CLI 默认不设总时限)

15.10稳定退出码

text
0  成功
1  未处理的运行时错误
2  语法或静态检查错误
3  CLI 用法错误
4  文件 I/O、进程或网络错误
5  超时或取消

自动化脚本应按稳定退出码而不是错误文本进行分支。

扩展 · 16

扩展系统

v1.7.1 进程扩展机制:官方签名 Registry、源码编译、包清单、权限声明、Protocol 1 与 callable 注册。

16.1HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

16.2当前已实现的扩展边界

v1.7.1 已实现本地 install/list/remove、Ed25519 签名 Registry、manifest 与 SHA-256 校验、隔离进程握手、动态 callable 注册、同步调用、结构化错误和 shutdown。脚本可以直接 import 已安装的扩展包。
能力当前状态边界
扩展分发已实现官方签名 Registry 或本地源码构建;安装前验证身份、target、签名与文件哈希
进程协议已实现handshake、register、call、call_result、error、shutdown
值传输已实现Null、Bool、数字、String、List、Map 的 JSON 协议映射
DB Stream / handle / cancelDB 1.0 已实现协商 scoped_resources、请求作用域句柄与取消;DB Stream 通过游标拉取,不等同于通用 Stream 传输
公开 Native ABI未承诺只有进程协议无法满足且有性能证据时再评估

包名就是顶级命名空间:package_name 只能注册 package_name.*,不能覆盖 hhy.*、std.*、核心 callable 或其他包。导入未安装的包会得到 ModuleNotFoundError。

16.3现有官方扩展

扩展版本发布时间状态能力
database1.0.02026-09-07已发布MySQL/PostgreSQL 连接池、远程 TLS、读写事务、预处理、游标与精确类型
html0.2.02026-09-01已发布Lexbor CSS Selector、文本/属性读取与结构化抽取

数据库扩展使用指南
安装 database 1.0.0,配置连接池、远程 TLS、事务和流式查询。
/zh/learn/database-extension

HTML 扩展与抓取框架
使用 html 0.2.0、可观察批量抽取、URL 规范化、安全 Frontier、去重和 SSRF 防护构建静态 Spider。
/zh/learn/html-crawler-framework

16.4在哪里获取扩展

来源适合场景地址或操作
HHY 官方 Registry下载经过签名、按平台区分的官方扩展https://registry.hhylang.dev(索引:/index.json;信任根:/root.json)
GitHub 源码查看代码、审计变更或自行编译https://github.com/hh696-wq/hhy-vm/tree/main/extensions
本地自行编译开发扩展或需要本机依赖组合make -C extensions/<name>,然后从本地目录安装
sh
# 从源码构建并安装(示例:html)
git clone https://github.com/hh696-wq/hhy-vm.git
cd hhy-vm
make
make -C extensions/html
./build/hhy install ./extensions/html

# 查看已安装扩展
./build/hhy list

查看官方扩展索引 ↗
同一扩展版本按 darwin-arm64、linux-x86_64、linux-arm64 和 windows-x86_64 分发,安装器只选择当前平台 target。
https://registry.hhylang.dev/index.json

在 GitHub 查看扩展源码 ↗
包含 sample、html 与 database 的源码、hhy.toml、测试和构建脚本。
https://github.com/hh696-wq/hhy-vm/tree/main/extensions

Database 1.0.0 提供独立 GitHub Release,也随 HHY 的 macOS/Linux 包分发;Windows Runtime 包不包含 DB。Registry 可用版本以签名索引为准。自行编译时必须在目标操作系统和架构上构建,不能把 macOS 二进制改名用于 Linux 或 Windows。

16.5安装、查看与移除

sh
./build/hhy install ./path/to/extension
./build/hhy list
./build/hhy remove package-name
步骤实际行为
install读取 hhy.toml;校验包名、作者、requires_hhy、协议、命令和完整性;展示 capability 后由用户确认安装
import / load重新校验已安装文件的 SHA-256,启动扩展进程,握手并注册 callable
list显示已安装包的名称、版本、作者、协议和声明的 capability
remove删除本地包记录和安装目录;之后 import 会失败
默认扩展目录是 ~/.hhy/extensions;设置 HHY_EXTENSION_HOME 可为 CI 或测试提供隔离目录。capability 是安装时可审查的声明,不等同于通用操作系统沙箱;第三方扩展仍应按原生可执行文件对待。

16.6通用 hhy.toml 清单

text
[package]
name = "package-name"
version = "0.1.0"
author = "Your Organization"
requires_hhy = ">=1.1,<2.0"

[extension]
kind = "process"
command = "bin/hhy-package"
protocol = "1"

[capabilities]
read = []
write = []
network = []
process = false
字段开发者约束
package.name唯一顶级命名空间,只允许小写字母、数字和连字符
package.author安装与 list 时展示,明确官方或第三方来源
requires_hhy安装器检查 Runtime 版本范围
extension.command必须是包内 bin/ 下的可执行文件,不能逃出包目录
extension.protocol当前只接受 Protocol 1
capabilities声明需要审查的文件、网络和子进程访问范围

16.7扩展如何加载

扩展加载流程

HHY 脚本 → Runtime 校验 → 隔离扩展进程 → 协议注册 → 调用执行 → 结构化结果或错误。

阶段Runtime 与扩展的职责
resolveRuntime 根据 import package_name 定位已安装包,解析清单并校验命令与完整性
spawnRuntime 以 --protocol 1 启动独立进程,并建立 stdin/stdout 协议管道
handshake双方确认 extension_id 与 protocol_version=1.0
register扩展发送一次注册消息;Runtime 验证包命名空间和 contract 后写入 callable registry
callRuntime 发送可序列化参数;request_id 关联 call 与 call_result
shutdownRuntime 发送 shutdown 并回收协议流和子进程
Runtime 调用仍是同步的。HHY 1.5.0 为声明 scoped_resources 的 DB 扩展增加作用域结束与取消消息;句柄是请求内资源标识,DB Stream 在宿主中按批拉取游标。通用 Stream credit 和公开 Native ABI 未开放。

16.8扩展作者需要实现什么

部分要求
包提供 hhy.toml、包内可执行命令和安装器可验证的 SHA-256 完整性信息
启动只接受 --protocol 1;协议消息只写 stdout,日志写 stderr
handshake验证 extension_id 与 protocol_version,并返回匹配身份
register恰好发送一次初始注册;名称必须位于包命名空间且 contract 完整
call按 request_id 返回 call_result 或结构化 error,不泄露凭据或敏感诊断
shutdown幂等释放连接、内存和其他扩展资源
测试至少覆盖身份不匹配、非法参数、扩展退出、协议错误和资源清理

扩展进程不会继承完整宿主环境;Runtime 只通过协议传递脚本显式提供的参数。错误应可定位,但不得包含密码、令牌、完整连接地址或其他敏感信息。

扩展 · 17

数据库扩展使用指南

Database 1.0.0:MySQL/PostgreSQL 连接池、远程 TLS、事务、预处理、游标、精确类型与 HHY Stream,最低 HHY 1.5.0,已验证兼容 1.7.0。

17.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

17.2版本与安装

DB 1.0.0 于 2026-09-07 随 HHY 1.5.0 发布。数据库扩展独立版本化;支持 macOS arm64、Linux arm64/x86_64,Windows Runtime 包不包含 DB。

下载 Database 1.0.0
HHY 1.5.0 · Database 1.0.0
https://github.com/hh696-wq/hhy-vm/releases/tag/database-v1.0.0

sh
hhy --version
# Extract the matching release archive and preserve bin/ and lib/
hhy install ./hhy-database-1.0.0-darwin-arm64
hhy list

# Or build from the repository root
make -C extensions/database
./build/hhy install ./extensions/database

17.3连接配置与远程 TLS

config.local.json
{
  "driver": "mysql",
  "host": "127.0.0.1",
  "port": 3306,
  "user": "cms_test",
  "password": "CHANGE_ME",
  "database": "hhy_test",
  "allow": [
    "127.0.0.1:3306"
  ],
  "tls": "disabled",
  "max_open": 4,
  "max_idle": 2,
  "connect_ms": 5000,
  "acquire_ms": 1000,
  "timeout_ms": 30000
}
示例只连接专用本地测试库。保护配置文件并排除 Git;生产凭据从环境或密钥来源读取。远程数据库必须使用配置 Map:host 填真实地址,allow 精确列出 host:port,tls 使用 verify_identity,ca 指向 CA 证书。VPC、白名单与数据库授权由部署环境负责;RDS 实机尚未验收。

旧 URL 调用继续支持 loopback 地址;远程连接和池选项使用 Map。MySQL 占位符为 ?,PostgreSQL 为 $1、$2;标识符不能作为值参数。allow 是可信脚本策略,不是操作系统沙箱。

17.4连接池与查询

query.hhy
import database
let cfg = read_text(path(args[0])) |> parse_json
database.query(cfg, "SELECT ? AS value", [42], { typed: true }) |> print
database.stats() |> print
sh
hhy run query.hhy ./config.local.json

连接池按数据源和扩展进程隔离。max_open 默认 4、max_idle 默认 2;多 Worker 的总连接数需要累加。支持空闲/寿命回收、连接重置、借用超时和统计。Duration 配置如 timeout_ms: 5s 可直接传给 DB。默认结果保持 String/null;typed 模式保留数值类型,Decimal/大整数用精确封装,二进制映射 BytesBuffer。

17.5读写事务与流式查询

以下示例要求已存在 pages(id, title) 测试表;PostgreSQL 请替换占位符。事务闭包成功提交、异常回滚。MySQL DDL 不属于多步原子事务;安装程序需记录迁移检查点。
transaction.hhy
import database
let cfg = read_text(path(args[0])) |> parse_json
cfg |> database.with_transaction { tx ->
    database.execute(tx, "UPDATE pages SET title = ? WHERE id = ?", ["Hello HHY", 1])
    database.query(tx, "SELECT id, title FROM pages WHERE id = ?", [1])
} |> print
stream.hhy
import database
let cfg = read_text(path(args[0])) |> parse_json
database.stream(cfg, "SELECT id, title FROM pages ORDER BY id", [])
    |> take(100)
    |> collect
    |> print

Stream 按批拉取,take 会提前关闭结果。句柄不能跨请求、Worker 或 close 后使用;请求结束清理遗留资源。未读完的结果可能导致物理连接丢弃,在事务内提前结束流时需留意事务失效。

17.6API 与边界

API用途
ping / query / execute连接检查、查询与写入
connection / begin / commit / rollback / close作用域连接和事务
with_transaction / savepoint / rollback_to / release_savepoint事务闭包与保存点
prepare / query_prepared / execute_prepared同一连接复用服务端预处理
transaction / execute_many1–100 条原子批量 DML
cursor / fetch / next_result / close_result / stream增量结果;next_result 支持 MySQL
stats / capabilities指标与版本能力
字段上限 64 KiB、协议消息 1 MiB,有界 query 最多 10000 行并报告截断。池饱和返回 DB_POOL_TIMEOUT;取消和超时可能销毁连接。DB_COMMIT_UNKNOWN 表示提交结果不确定,不能自动重放写入。

17.7验收与安装场景

MySQL 8.4/PostgreSQL 17、本地与 CI、AST/Bytecode、双 Worker、TLS 正反例、取消、sanitizer、百万行本地流式已验收。install.hhy 数据库夹具覆盖失败恢复、重复安装、升级回滚和备份恢复;不是完整 CMS。每库本地持续测试 5 分钟,未宣称 24 小时长稳或 RDS 故障切换通过。

完整 API 与迁移说明
HHY 1.5.0 · Database 1.0.0
/docs/DATABASE_1.0.0_README.md

原始数据摘要与重现方式
HHY 1.5.0 · Database 1.0.0
/docs/DATABASE_1.0.0_ACCEPTANCE.md

查看通过的发行 Actions
HHY 1.5.0 · Database 1.0.0
https://github.com/hh696-wq/hhy-vm/actions/runs/34079510695

扩展 · 18

HTML 扩展与抓取框架

用官方 HTML 扩展和安全 Frontier 完成 URL 规范化、链接发现、递归去重及有界静态抓取。

18.1HTML 扩展是什么

官方 html 0.2.0 是一个无网络、无文件副作用的进程扩展。它用 Lexbor 解析不可信 HTML、执行 CSS Selector,并通过 extract_report 返回批量记录和明确的截断元数据。

HTML 扩展只负责解析和抽取,不下载 URL、不调度页面,也不返回 DOM handle。HTTP、TLS、超时、重试和安全策略由 HHY Runtime 与上层爬虫框架负责。

18.2构建与安装 HTML 扩展

sh
brew install jansson lexbor
make -C extensions/html
./build/hhy install ./extensions/html
./build/hhy list
完整签名用途
html.text(String html, String selector, Map?) -> String?读取首个节点的规范化文本
html.text_all(String html, String selector, Map?) -> List<String>读取全部匹配节点的文本
html.attr(String html, String selector, String name, Map?) -> String?读取首个节点的属性
html.attr_all(String html, String selector, String name, Map?) -> List<String>读取全部匹配节点的属性
html.exists(String html, String selector) -> Bool判断 Selector 是否命中
html.extract(String html, String selector, Map schema, Map?) -> List<Map>一次解析文档,并按 schema 投影重复记录
选项适用方法行为
trim: Booltext、text_all、attr、attr_all是否清理首尾空白,默认开启
max_results: Inttext_all、attr_all、extract默认 1000,硬上限 10000

扩展把输入限制在 768 KiB,以便协议消息始终有界。extract 的 schema 字段使用 { selector, value: "text" } 或 { selector, value: "attr", name };空 selector 表示读取当前 root。它不返回 DOM handle:Protocol 1 只运输 JSON 可表达的值,因此 html.extract 在扩展内一次完成解析和字段投影。

18.3从 HTML 扩展到安全爬虫框架

静态 Spider 把多个职责组合成闭环:Runtime 的 url_resolve 规范化并解析相对 URL;HTML 扩展发现链接;按深度推进的 Frontier 在入队前检查域名、路径、页面数、队列大小和请求指纹;HTTP 网络层在实际连接地址上阻止 SSRF。

能力当前实现程度
url_resolve(url, base?)返回 url、scheme、host、port、path、query 与稳定 fingerprint
链接发现follow_selector 提取 href,逐层加入 Frontier
Frontier 与去重按深度、有界并发;规范 URL 指纹在入队前去重
边界限制allowed_domains、path prefixes、max_depth/pages/frontier/links
SSRF 防护在每次实际 socket 连接时阻止 loopback、私网及 link-local,覆盖重定向

18.4适用范围与明确边界

当前支持内存或原子 checkpoint Frontier、严格配置匹配的断点恢复,以及 send_to 流式响应文件。可选 Playwright Renderer 能执行 JavaScript;它与无副作用的 Lexbor HTML 扩展隔离,并对主文档、重定向和子资源执行域名与 DNS 私网检查。

不要用它绕过 robots.txt、登录、验证码或反爬策略。只采集你有权访问的站点,并保持可识别 User-Agent、保守并发和明确页面上限。

路线图 · 19

语言与 VM 演进路线图

v1.7.1 当前验收记录,以及面向原子状态、跨 Worker 共享内存、协程和分布式事务的大版本规划。

19.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

19.2HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

19.3语言 / VM 演进路线图

当前 v1.7.1 · Database 1.0.0 已发布,延续完整 Web Runtime

版本发布日期主要变化验收状态
v1.0.0 · 已发布2026-08-25核心语言与 VM 语义冻结Pipe、Value、Stream、Error、核心标准库和三平台发行证据完成
v1.1.0 · 已发布2026-08-26本地进程扩展与官方数据库扩展安装/加载完整性、Protocol 1 同步调用、database 0.2.0 和三平台发行证据完成
v1.1.1 · 已发布2026-08-27性能优化与临界资源稳定性hhy profile、解释器热点基线和 Runtime 资源边界完成
v1.1.2 · 已发布2026-08-27HTML 扩展与静态采集框架三平台 CI、扩展协议测试、本机 fixture 与真实 hhylang.dev 抓取完成
v1.1.3 · 已发布2026-08-28Runtime 正确性与性能加固GC 压力回归、sanitizer、哈希索引、稳定诊断与三平台发布证据完成
v1.1.4 · 已发布2026-08-28安全静态 SpiderURL 规范化、链接发现、Frontier、边界、指纹去重与连接级 SSRF 防护
v1.1.5 · 已发布2026-08-30可恢复 Spider 与浏览器渲染持久 Frontier、断点恢复、流式落盘、可选 Playwright 与 Windows MSYS2 构建证据
v1.1.6 · 已完成2026-08-31稳定基线与测试治理宿主能力探测、分层 CI、机器可读性能基线与发布一致性门禁
v1.1.7 · 已完成2026-08-31诊断与编辑器基线版本化 JSON diagnostics、Contract Registry JSON、最小 LSP 与 VS Code 编辑闭环
v1.1.8 · 已完成2026-08-31Runtime 渐进治理首个模块边界、内部所有权 API、sanitizer/GC stress 与阻断式性能回归门禁
v1.2.0 · 已发布2026-08-31官方扩展分发与签名命名空间身份、Ed25519 签名索引与包描述、确定性依赖解析、dry-run 和事务式安装
v1.2.1 · 已发布2026-09-01锁定、离线与安全回滚同一 lock 得到同一依赖图;离线可重建;失败升级不破坏旧环境
v1.2.2 · 已发布2026-09-01官方 HTML 复杂扩展验证真实 fixture、可观察截断、结构化错误和四平台发行全部通过
v1.3.0-alpha · 已预发布2026-09-01Bytecode 编译器骨架核心语法可编译;非法 Bytecode 可拒绝;AST 仍为默认引擎
v1.3.0-beta · 阶段门禁已完成并入 v1.3.0Bytecode VM 执行核心执行桥、Verifier、资源边界和完整双引擎 fixture 已验收
v1.3.0-rc · 阶段门禁已完成并入 v1.3.0性能、Profiler、Stack trace 与默认切换门禁三平台和故障证据已完整;CPU 收益门槛未通过,因此 AST 保持默认
v1.3.0 · 已发布2026-09-01可选 Bytecode 正式执行路径完整套件双引擎通过;性能决策保持 AST 默认并保留显式回退
v1.3.1 · 已发布2026-09-01真实负载兼容加固官方 workload 双引擎矩阵和能力探测证据已通过三平台 CI
v1.3.2 · 已发布2026-09-01VM 内部边界稳定化版本化 Bytecode Runtime 边界、静态治理与持续 AST oracle
v1.3.3 · 已完成并入 v1.3.5原生 Opcode 执行闭环正常 Bytecode 路径不再调用 AST evaluator,完整双引擎语义对照通过
v1.3.4 · 已完成并入 v1.3.5VM 数据路径优化1M CPU workload ratio 0.6805;短任务与 JSON/I/O 无明显回退
v1.3.5 · 已发布2026-09-01Bytecode 默认引擎run/profile/简写默认 Bytecode;AST 显式回退与 oracle 永久保留
v1.3.6 · 已发布2026-09-01Stream Int fusion 性能闭环安全形状保守融合;未知形状无损回退;双引擎与跨平台门禁通过
v1.3.7 · 已发布2026-09-01特化实现加固具名 metadata、统一 stack/error、fallback reason 与三路径差分通过
v1.3.8 · 已发布2026-09-01Compiler/Verifier 优化 IRRuntime 不读取 AST 形状;Stream Kernel 独立验证并可靠回退
v1.3.9 · 已发布2026-09-01Profiler 与资源一致性普通执行与观测共用优化决策;开销、取消和 Heap 归因门禁通过
v1.3.10 · 已发布2026-09-01Bytecode 缓存治理五负载实测未达准入门槛;不实现缓存,不接受未验证外部 Bytecode
v1.3.11 · 已发布2026-09-02Runtime 错误路径加固结构化错误完整构造后发布;原始 fuzz 输入纳入永久回归
v1.4.0 · 已完成2026-09-03Web Runtime 基础Embedding、应用一次加载、handler 重复调用与请求隔离门禁完成
v1.4.1 · 已完成2026-09-03Web MVPHTTP/1.1、Router、Query/Header/Cookie、JSON API 与稳定错误完成
v1.4.2 · 已完成2026-09-03Web 应用能力Middleware、静态文件、上传、CORS、signed cookie、gzip 与热重载完成
v1.4.3 · 已发布2026-09-03流式与多 WorkerSSE、Stream、大文件 Range、多进程和可观测性完成;百万请求 0 失败
v1.5.0 · 已发布2026-09-07Database 1.0.0 与 Runtime 资源集成连接池、远程 TLS、事务、游标、精确类型、取消与 Worker 隔离;双数据库、双引擎和发行 Actions 通过;RDS 实机待验收
v1.6.0 · 评估交付2026-09-08指令选择与 dispatch 画像版本化 opcode/pair/triple 统计与开关交付;superinstruction 未达准入门槛;随 v1.7.0 发布
v1.6.1 · 实现交付2026-09-08调用、Closure 与异常展开紧凑调用布局、闭包路径与异常区域表实验通过差分验证;显式启用,随 v1.7.0 发布
v1.6.2 · 评估交付2026-09-08条件式 inline cacheMap slot 实验与稳定/变化调用点评估完成;未达默认准入门槛,保留通用回退;随 v1.7.0 发布
v1.6.3 · 评估交付2026-09-08GC、内存与调度决策分配/暂停及调度需求评估完成;未准入新的 GC 或 async scheduler;决策随 v1.7.0 交付
v1.7.0 · 已发布2026-09-08Optimizing Compiler & Runtime四平台 CI 与发行验收通过;HIR、六个 pass、整数 MIR、guard/deopt、局部 List 标量替换交付;优化默认关闭
v1.7.1 · 当前2026-09-14资源生命周期修复;七个默认关闭的受控并发实验 API。完整 1.7.x 路线仍按验收逐项推进。已通过本地 Release、ASan/UBSan、69 个引擎/配置用例、MySQL/PostgreSQL 幂等与未知提交对账、120 秒长稳、10 万请求 Web 测试,以及四平台 CI 与发行验收。七个实验 API 默认关闭;24 小时长稳、真实断电和完整故障矩阵仍待完成。

19.4后续规划

后续规划以原子性、共享状态、协程和分布式事务为主线,仅展示大版本方向。下面都是计划目标,尚未完成的能力不属于 1.7.1 当前保证。

大版本目标拆分里程碑开放与验收条件
1.x · 稳定现有能力先完成现有七个接口的稳定化,建立共享状态与协程所需的所有权、效果和资源契约。单 owner 原子状态 → 协作文件更新 → 严格数据库事务与有界任务,分别验收后取消实验开关。当前候选 24h 长稳、故障矩阵、AST/Bytecode 对等、平台与资源验收;未通过项继续实验。
2.x · 原子状态与协程内核实现语言域内全局原子性、跨 Worker 共享内存原子状态与协程调度器。共享 arena 与代际句柄 → 多对象读写集与统一提交 → 挂起帧、非阻塞 I/O 与结构化取消 → 联合稳定化。共享事务历史检查、崩溃恢复、GC roots、无丢失唤醒、公平性、资源上限与旧模式兼容;新语言模式通过后稳定开放。
3.x · 分布式事务把一致性能力扩展到支持事务协议的跨节点参与者。持久协调器 → prepare/commit/rollback 适配 → UNKNOWN 查询与恢复 → 高可用、故障注入和运维工具。参与者崩溃、网络分区、重复消息、决策日志与恢复验收;仅对已验证参与者稳定开放,外部基础设施仍需配置。
“全局原子性”限定为一个 StateDomain 内的受管共享状态,多对象事务统一提交;不是任意普通变量、HTTP、文件和数据库自动一起回滚。共享内存先覆盖同机 Worker;分布式事务仅覆盖支持协议的参与者,补偿工作流不等于原子回滚。
默认关闭项什么时候开放开放的含义
现有七个实验 API1.x 稳定化阶段,按状态、文件、DB、任务分别通过验收后开放。无需 HHY_CONCURRENCY_EXPERIMENTS 即可调用;仍需显式使用 API,不改变普通变量语义。
跨 Worker 原子状态与协程2.x 内核阶段先实验,联合正确性、恢复与资源门槛通过后开放。新模式稳定可用,旧程序不自动切换共享或调度语义。
分布式事务3.x 持久协调与参与者验收通过后开放。稳定 API 仍需数据库/协调器配置,不自动接管所有外部效果。
Compiler / cache / fusion 等性能候选不绑定必开版本;真实负载收益、兼容性和资源预算全部通过才逐项默认开启。可以长期关闭;代码已实现或正确性通过不代表性能准入。

版本方向不构成日期承诺。1.7.1 现在可通过 HHY_CONCURRENCY_EXPERIMENTS=1 试用七个接口;稳定 API 可用与性能优化默认执行分别决策,验收失败就顺延,不降低门槛。

查看当前原子性与并发保证
区分已支持、实验能力和未来规划
/zh/learn/concurrency-scopes

19.5演进原则

原则约束
语义先冻结Pipe、Value、Stream、Error 与取消语义先稳定,再扩展生态表面
可用、可测先于高性能每项能力先具备确定错误、资源上限和跨平台测试,再进行优化
协议优先第三方能力优先通过 Process Extension Protocol 接入,不并行发明第二套语言语义
ABI 有条件开放Native ABI 只有在 Runtime 足够稳定且测量证明必要时才评估;不开放也是有效结论

路线图每个季度应重新评审一次:只调整尚未冻结版本;已经发布的语义、协议兼容承诺和迁移路径不能因排期变化而被削弱。

19.6明确不在路线中承诺的事项

  • 不会为了版本号引入第二套 Pipe、Stream 或 Error 模型。
  • 不会在缺少兼容策略时直接公开 Runtime 内部 C 结构体。
  • 不会把建议时间窗口当作牺牲测试、安全或跨平台验证的理由。
  • 不会同时推进远程包仓库、Native ABI 和多套官方扩展而绕过阶段验收。

工具 · 20

编辑器语言支持

下载并安装 VS Code 与 Sublime Text 的 HHY 语言包。

20.1HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

20.2下载语言包

插件提供 .hhy 语法高亮、括号、缩进与代码片段。VS Code 版还通过 hhy CLI 提供诊断、格式化、定义跳转、Hover 与补全;请先安装 HHY Runtime。插件版本独立于 Runtime。

本站下载编辑器插件
提供可直接安装的 VSIX 和 sublime-package,以及 SHA-256 校验文件。
/zh/downloads#editors

20.3安装到 VS Code

sh
code --install-extension ./hhy-language-support-0.2.0.vsix

在下载目录执行,也可在 VS Code 扩展菜单选择“从 VSIX 安装”。安装后打开 .hhy 文件。

20.4安装到 Sublime Text

把下载的 HHY-0.1.0.sublime-package 复制到 Sublime Text 的 Installed Packages 目录,然后打开 .hhy 文件。

语言报告 · 21

HHY 语言状态报告 · 2026-09-14

发布 HHY 当前语义、Runtime、性能与工程质量状态,包含可复核的 CI 实测数据。

21.11.7.1 受控并发与原子性

本版修复资源生命周期并交付七个默认关闭的实验接口。请先了解状态所有者、协作文件锁、严格事务以及有界任务的保证边界。

阅读完整指南与示例
包含保证矩阵、错误处理和实际验收证据
/zh/learn/concurrency-scopes

21.2HHY 1.7.1 当前实现与兼容性

1.7.1 已通过本地测试、四平台 CI 和发行验收。语言规范仍为冻结的 1.0;官方 sample、HTML 以及 macOS/Linux Database 1.0.0 扩展已验证兼容。VS Code 0.2.0 与 Sublime 0.1.0 保持独立版本,语法和编辑器契约检查通过。

HIR、六个优化 pass、整数 MIR、类型反馈 guard/deopt 与局部 List 标量替换已交付。使用 HHY_COMPILER=ir、HHY_FEEDBACK_SPECIALIZATION=1、HHY_SCALAR_REPLACEMENT=1 显式启用;默认直接 Bytecode 不变。真实负载收益尚未满足默认启用门槛,标量替换保留原始 GC/配额预约。

优化开关、验证与支持范围
v1.7.1 实施说明
/docs/COMPILER_IR.md

1.7.1 发行说明
已发布能力与边界
/docs/RELEASE_NOTES_1.7.1.md

21.31.7.0 历史实测与发布证据

2026-09-08 本地 macOS arm64,HHY 1.7.0,默认编译配置,单次 profiler 原始输出如下。仅 4 个 CPU 样本,短任务热点比例和计时会波动,不用于判定性能提升。

$ hhy profile --engine bytecode examples/09-profile-algorithms.hhy -- fibonacci 20
HHY profile: examples/09-profile-algorithms.hhy

Summary
  Engine           bytecode
  Wall time        0.013 s
  CPU time         0.008 s
  CPU utilization  58.8%
  CPU samples      4
  Heap peak        1.8 MiB
  Heap after GC    92.0 KiB
  Allocated        1.7 MiB
  Allocations      33040

CPU hotspots
  CPU%    Samples      Calls  Function
   75.0%        3      21891  fibonacci  examples/09-profile-algorithms.hhy:5:1
   25.0%        1          1  print  examples/09-profile-algorithms.hhy:18:6
    0.0%        0          1  <bytecode-top-level>  examples/09-profile-algorithms.hhy:1:1
    0.0%        0          1  length  examples/09-profile-algorithms.hhy:12:10
    0.0%        0          1  to_int  examples/09-profile-algorithms.hhy:17:19
  Note: fewer than 10 CPU samples; use a larger workload for stable results.

Allocation hotspots
  Bytes          Objects  Function
  1.7 MiB            32856  fibonacci  examples/09-profile-algorithms.hhy:5:1
  11.6 KiB              184  <bytecode-top-level>  examples/09-profile-algorithms.hhy:1:1

fibonacci 6765
平台整数 MIR / 基线局部 List / 基线
linux-arm640.7624×0.7495×
linux-x86_640.7067×0.6738×
macos-arm640.8392×0.8553×
windows-x86_640.8478×0.8326×
四平台数据来自发布提交 8fb0b8f 的 CI 34197497786,各 15 对交错样本。表中两个合成负载通过预算;core/json/closure 真实负载未达到 5% 收益门槛,优化仍默认关闭。标量替换保留原始 GC/配额预约。下方旧版本实测保留历史口径。

查看 1.7.0 CI 与原始性能 artifacts
8fb0b8f · 2026-09-08
https://github.com/hh696-wq/hhy-vm/actions/runs/34197497786

21.4发布摘要

截至 2026-09-14,HHY v1.7.1 已发布 Database 1.0.0 与资源作用域集成,并保留完整 Web Runtime:可嵌入 Runtime、HTTP/1.1、Router、Middleware、上传、流式响应、SSE、多 Worker 与可观测性。v1.4.0–v1.4.2 是能力里程碑,统一由 v1.4.3 正式发行。Bytecode 保持默认,AST 保留为语义 oracle 和显式回退。
报告维度回答的问题当前结论
语言基线核心语义是否稳定Pipe、Value、Stream、Error 与核心 callable contract 保持稳定,AST/Bytecode 持续对照
Runtime 健康度资源、内存与取消边界是否可靠资源上限、GC stress、sanitizer、fuzz、故障注入与显式所有权治理通过
执行引擎Bytecode 是否适合默认启用原生 Opcode 路径语义门禁与性能门禁通过,Bytecode 默认,AST 可显式回退
工程治理变化是否可审计四平台 CI、真实 workload、分层门禁、版本一致性和发行证据形成闭环

21.5本期数据概览

数据项结果证据口径
当前正式版本v1.7.1四平台 Release、逐包 SHA-256 与 SHA256SUMS
执行引擎Bytecode 默认 / AST 回退完整双引擎套件与机器可读决策
核心 callable128Runtime Callable Contract Registry
持续验证平台4 个macOS arm64、Linux arm64、Linux x86_64、Windows x86_64
v1.3.10 CI 引擎基线历史测量通过1M CPU 0.3695;短任务 1.0088;持续 JSON 1.0207
v1.3.10 Profiler 开销1.0269× / +2.786 ms历史 9 次样本;门槛 1.35× 且 12 ms
Bytecode 缓存不准入5 个负载 × 21 次;compile+verify 不构成主要成本
完整实战项目6 个AST/Bytecode 端到端 acceptance 与稳定退出码

21.6v1.5.0 / Database 1.0.0 发布验收

2026-09-07 发布。双数据库、双引擎、TLS、作用域清理、取消、CMS 安装数据库流程与跨平台发行门禁通过;本地百万行流式及每库 5 分钟持续测试报告可查。RDS 和 24 小时长稳仍待验证。

查看 DB 1.0.0 验收记录
HHY 1.5.0 · Database 1.0.0
/docs/DATABASE_1.0.0_ACCEPTANCE.md

查看 HHY 1.5.0 发行说明
HHY 1.5.0 · Database 1.0.0
/docs/RELEASE_NOTES_1.5.0.md

21.7v1.4.3 Web Runtime 与发布验证

验证项结果测量范围
可嵌入 Runtime100,000 次重复调用单个已加载 Context;AST/Bytecode 输出差分检查
HTTP 压力验证1,000,000 次请求 · 0 失败发布验证主机 loopback,16 个并发客户端
HTTP 耗时与吞吐131.439 秒 · 7,608.1 请求/秒上述短请求负载的主机实测,不代表公网或业务服务吞吐
HTTP 功能回归端到端覆盖Router、Query、404/405/413/500、错误后恢复、Middleware、静态缓存、上传清理、CORS、signed cookie 与 gzip
流式与运维端到端覆盖Stream、SSE、Range、metrics、health、多 Worker 与开发热重载
本节引用 v1.4.3 发行验证记录,并非 2026-09-04 重新压测。下方 CPU、Profiler、缓存与六语言比较保留原始 v1.3.10 版本和测量口径。

查看 v1.4.3 发行验证记录
本站保存的发行说明,包含测试规模、结果与能力边界。
/docs/RELEASE_NOTES_1.4.3.md

21.8当前能力边界

范围当前边界
HTTP 服务Runtime 提供 HTTP/1.1;TLS 和 HTTP/2 由 Caddy、Nginx 或负载均衡器承担
WebSocket不在 v1.4 能力范围内
执行引擎Bytecode 默认,保留 AST 回退;不提供 JIT、进程/磁盘 Bytecode 缓存或未验证外部 Bytecode 加载
原生集成C Embedding 使用 opaque 句柄和 JSON ABI;不等于开放 Runtime 内部结构或第三方 Native Extension ABI

21.9总体基线与兼容性

基线稳定承诺验证方式
语言语义不引入第二套 Pipe、Stream 或 Error 模型规范示例、Parser/Checker fixtures 与合法程序回归
Callable contract名称、arity、effect、lazy、cancellable 和 threading 可机器读取Contract Registry JSON 与当前 callable contract 一致性检查
诊断CLI 文本与 JSON/LSP 使用同一 Core 检查路径诊断 schema 与 LSP 协议测试
扩展边界第三方能力优先走 Process Extension Protocol清单完整性、Protocol 1 与官方扩展验收
C Embedding公开 opaque Application/Context 句柄与 JSON ABI,不公开 Runtime 内部结构单次加载、重复调用、请求隔离与 AST/Bytecode 差分验证

当前正式基线为 v1.7.1。Bytecode 是默认引擎,AST evaluator 继续作为语义 oracle,可通过 --engine ast 或 HHY_ENGINE=ast 显式使用。Compiler 产生的 Stream Kernel 必须独立通过 Verifier;动态或未知形状无损回退通用 Bytecode。

21.10v1.2.2 发行与扩展状态

能力当前状态验收结果
扩展分发Ed25519 签名 Registry、确定性依赖解析篡改、来源不明和依赖冲突稳定拒绝
可复现环境Lockfile、content-addressed 离线缓存同一 lock 得到同一依赖图,干净环境可离线重建
安全变更事务式安装、升级和显式回滚失败升级不破坏旧环境
HTML 0.2.0Lexbor、CSS selector、单次解析多字段投影畸形 HTML、硬上限、截断和结构化错误通过四平台验收
协议决策保留同步有界批量 APIHTML 保持同步批量;DB 1.0 已使用作用域句柄、取消和宿主游标 Stream;通用 Stream credit 未开放
v1.2.2 正式 Release 已包含 macOS arm64、Linux x86_64、Linux arm64、Windows x86_64 归档、逐包 SHA-256 与合并 SHA256SUMS。HTML 扩展保持 effect = none,不自行读取文件、访问网络或执行子进程。

查看 HHY Language v1.2.2 正式发行
下载四平台归档、校验文件并查看完整发行说明。
https://github.com/hh696-wq/hhy-vm/releases/tag/v1.2.2

21.11v1.3.7–v1.3.10 Bytecode 加固状态

版本核心交付已验证结论
v1.3.7具名 specialization metadata、统一 stack/error、fallback reason无 magic kind;三路径差分与变形测试通过
v1.3.8Compiler 生成版本化 Stream Kernel IRRuntime 不读取 AST 形状;Kernel 独立 verify;动态形状安全回退
v1.3.9普通执行与 Profiler 共用优化决策kernel/opcode、取消、CPU/Heap 归因与机器报告一致;开销门禁通过
v1.3.10真实性能触发的缓存治理数据未触发准入;无进程/磁盘缓存;不接受未验证外部 Bytecode
四个版本均按顺序完成实现、Release/Debug 测试、sanitizer、fuzz、真实性能、四平台 Actions、正式 Release 和 Homebrew Formula 校验后才进入下一版本。

查看 HHY Language v1.7.1 正式发行
包含四平台归档、逐包 SHA-256、SHA256SUMS 与 Web Runtime 发行说明。
https://github.com/hh696-wq/hhy-vm/releases/tag/v1.7.1

21.12历史性能基线 · v1.3.10

最终 v1.3.10 CI 数据来自提交 4ddc8c3、GitHub Actions Ubuntu 24.04 的 schema-2 paired/interleaved benchmark 和独立 Profiler/缓存决策 artifact。数值是 Bytecode/AST 墙钟比;小于 1 表示 Bytecode 更快。

门禁实测上限结果
1M CPU0.3695×0.90×通过
短任务1.0088×1.25×通过
持续 JSON/I/O1.0207×1.10×通过
Profiler 开销1.0269× / +2.786 ms1.35× / +12 ms通过
缓存准入负载compile+verify 中位数冷运行中位数占比
Hello0.0097 ms5.860 ms0.1649%
Advanced Flow0.0269 ms5.916 ms0.4546%
Stdlib0.0286 ms7.003 ms0.4086%
Sustained JSON0.0089 ms33.518 ms0.0266%
Core Flow 1M0.0105 ms166.285 ms0.0063%
缓存联合门槛为 compile+verify ≥ 1 ms 且占冷运行 ≥ 20%。五项均远低于门槛,即使假设缓存读取成本为零也无可复现收益,因此 v1.3.10 不实现进程/磁盘缓存,并继续拒绝未验证外部 Bytecode。

21.13v1.3.10 六语言同机重测

2026-09-01 在 macOS 26.6.2 arm64 上重新实测 HHY 1.3.10、PHP 8.5.10、Go 1.27.0、Python 3.14.7、Lua 5.5.1 和 OpenJDK 26.0.2.1。固定任务为 range(0, 1,000,000) → 乘 2 → 保留可被 3 整除的值 → 稳定去重 → 物化 → 计数;六种实现都验证输出 333334。每种语言先预热 2 次,再做两轮独立测量;每轮 7 个 fresh process,固定种子随机交错运行,墙钟包含进程启动;Go 与 Java 预先编译,编译时间不计入。

实现版本第 1 轮中位数第 2 轮中位数两轮范围
Go1.27.07.995 ms7.969 ms7.622–15.325 ms
Lua5.5.118.368 ms17.957 ms17.582–19.822 ms
PHP8.5.1043.174 ms43.549 ms42.588–49.033 ms
JavaOpenJDK 26.0.2.149.394 ms48.153 ms46.995–53.066 ms
HHY Bytecode1.3.1055.297 ms53.404 ms51.027–78.702 ms
Python3.14.781.747 ms86.459 ms79.993–87.774 ms
比较第 1 轮第 2 轮解读
HHY / PHP1.28×1.23×该任务 HHY 比 PHP 多用约 23%–28% 墙钟
HHY / Java1.12×1.11×包含 JVM fresh-process 启动时,Java 略快
HHY / Python0.68×0.62×HHY 在该任务上用时更少
HHY / Lua3.01×2.97×Lua 在该整数循环上更快
HHY / Go6.92×6.70×预编译 Go 显著更快
这是一个特定 CPU/物化 workload,不是通用语言排名。各实现使用惯用循环与去重容器;Java 使用 HashSet/ArrayList 并包含 fresh JVM 启动。全部 84 个计时样本、版本、顺序和源程序保存在本地 performance-analysis/2026-09-01-v1.3.10-language-comparison/,该目录按项目规则不提交 GitHub。

21.14治理结论与后续观察

  • 总体状态:v1.7.0 / DB 1.0.0 已通过本地、CI 与跨平台发行验收;RDS 实机和 24 小时长稳仍待补验。
  • Web 结论:可嵌入 Runtime、HTTP、Router、Middleware、上传、Stream/SSE、多 Worker 与可观测性一次性交付。
  • 执行引擎策略:Bytecode 默认;AST 永久保留为语义 oracle、差分测试和 --engine ast 紧急回退。
  • 性能结论:Web 百万短请求 0 失败;既有 CPU、短任务、持续 JSON 与 Profiler 门禁继续通过。
  • 缓存结论:compile+verify 不构成冷运行主要成本;当前不引入缓存,未来必须由新数据重新触发评审。
  • 更新规则:发布基线、测量方法、引擎/缓存决策或总体风险结论变化时同步更新本报告。

查看 v1.3.11 持续验证证据
四平台构建、sanitizer、fuzz、性能门禁与真实项目验收。
https://github.com/hh696-wq/hhy-vm/actions/runs/33581452558

HHYHHY Language

一门以 Flow 为核心的系统脚本语言。

© 2026 HHY Language contributors
学习快速开始完整手册CLI 参考
项目关于 HHY下载中心HHY CMS相关文章GitHub规范Apache 2.0
联系 hhylang.dev huiyang.hou@qq.comhouhuiyang.com