开发者生态
morning
Show HN:我用 Go 创建了一种类似 Clojure 的语言,在 7 毫秒内启动
2026-05-09
1 阅读
marcingas
放手问候乐福鞋! (λ-gophers 哈哈,明白了吗?)这是一个字节码编译器和虚拟机,适用于一种与 Clojure 非常相似的语言,如果您愿意的话,它是一种 Clojure 方言。 Go 中最小且启动速度最快的 Clojure 系列语言 — 单个约 10MB 的二进制文件,冷启动约 7 毫秒。为什么要放手?独立可执行文件 - 使用 lg -b myapp main.lg 将程序编译为单个二进制文件。不需要运行时,只需分发并运行。 WASM Web 应用程序 — 使用 lg -w outdir main.lg 将程序编译为独立的 HTML 页面。通过 xterm.js 进行完整终端模拟,可在任何浏览器中运行。部署到 GitHub Pages 或在本地打开。快速启动——6ms冷启动。即使使用大型标准库,预编译的字节码(LGB 格式)也能实现近乎即时的启动。占用空间小 — 10MB 二进制、14MB 空闲内存。比 Babashka 小 7 倍,比 JDK 小 30 倍。包含电池 — core.async 通道、HTTP 服务器/客户端、JSON、Transit、IO、Babashka pod、nREPL 服务器。 Go 互操作 - 在 Go 应用程序中嵌入 let-go,将 Go 结构映射到记录,从 let-go 调用 Go 函数,反之亦然。广泛的 Clojure 兼容性 — 宏、解构、协议、记录、多方法、转换器、延迟序列、持久数据结构、BigInts。以下是一些模糊的目标(排名不分先后):高质量娱乐、使在 Go 日常工作中编写 Clojure 变得合法、尽可能多地实现 Clojure — 包括持久数据类型、真正的并发、转换器、core.async 和 BigInts、为任意函数和类型提供舒适的双向互操作、AOT 编译 — 将 let-go 程序编译为字节码或独立二进制文件、在单个 requestAnimationFrame 中启动整个运行时,并且仍然有 10ms 的空闲时间60fps,使用终端仿真将 let-go 程序编译为独立的 WASM Web 应用程序,WASM 中的 nREPL 服务器 — 通过 WebSocket 将 Emacs/Calva 连接到在浏览器中运行的 let-go VM,拉伸目标:let-go 字节码 -> Go 翻译。以下是非目标:在任何时候成为 clojure/clojure 的直接替代品,总体上成为 Clojure 的 linter/格式化程序/工具。功能概述 let-go 的目的是让用户感觉像日常 Clojure,而不是简单的替代品。大多数惯用代码的读取、运行和行为都是相同的——但是一个不平凡的 Clojure 项目可能需要一些调整才能在不修改的情况下运行。请参阅下面的已知限制。 Clojure 兼容性 let-go 针对 jank-lang/clojure-test-suite (跨方言合规性套件)进行了测试:4696 / 4921 断言在 217 个测试文件中通过(95.4%)。剩下的差距主要是边缘情况(+ / - / * / inc / dec 上的溢出检测、Long 边界处的 BigInt 提升、BigDecimal 行为)和一些存根命名空间 - 见下文。工作流程指南:docs/clojure-test-suite.md。标准命名空间 命名空间 状态 clojure.core 宏、解构、延迟序列、变换器、协议、记录、多方法、原子、正则表达式、元数据、BigInt clojure.string 完整的 clojure.set 完整的 clojure.walk prewalk 、 postwalk 、 keywordsize-keys 、 stringify-keys 、 walk clojure.edn read 、 read-string clojure.pprint pprint , cl-format clojure.test deftest 、 is 、testing 、 are 、装置 clojure.core.async 通道、 go / go-loop 、 alts! , mult / pub , pipeline / merge / split (真正的 goroutine, 不是 IOC) io 多态读取器/写入器, slurp / spit , 懒惰的 line-seq, 编码, URL, 带开放 http 环形服务器 + 客户端, 流式响应 json read-json , write-json — 浮动保留, 记录感知的中转 transit+json 编解码器,带滚动缓存 os sh , stat , ls , cwd , getenv / setenv 、 exit 、 os-name 、 arch 、 user-name 、 hostname 、 分隔符 系统 JVM 型: getProperty 、 getProperties 、 getenv 、 exit 、 lineSeparator 、 currentTimeMillis 、 nanoTime 。公开 let-go.version 、 let-go.commit 、 user.home 、 user.dir 、 os.name 、 os.arch 等。 syscall 直接 Linux 系统调用(mount、unshare、mknod、prctl、capset、seccomp、AppArmor),用于系统编程 pod Babashka pods 通过 JSON / EDN / 传输 Babashka pods let-go 支持 Babashka pods - 公开的独立程序二进制协议上的命名空间。这让我们可以轻松访问整个 Pod 生态系统:数据库、AWS、Docker、文件监视等。 ; ;加载一个 pod(使用 babashka 的共享缓存)( pods/load-pod 'org.babashka/go-sqlite3 " 0.3.13 " ); ;像任何其他命名空间一样使用它( pod.babashka.go-sqlite3/execute! " app.db " [ " 创建表用户(id 整数主键,名称文本) " ]) ( pod.babashka.go-sqlite3/execute! " app.db " [ " insert into users values (1, ?) " " Alice " ]) ( pod.babashka.go-sqlite3/query " app.db " [ " select * from users " ]) ; ; => [{:id 1 :name "Alice"}] pods/load-pod - 按名称(路径)加载或从 babashka 缓存(符号 + 版本)加载 支持 JSON、EDN 和 Transit+json 有效负载格式 客户端代码评估(pod 定义的宏和包装器) 通过 pods/invoke 进行异步流处理:用于回调的处理程序 共享 ~/.babashka/pods/ cache - 使用 bb 安