# 实用工具
实用工具是不适合归入其他类别的小杂烩:恒等、显式应用与部分应用、运行时求值、模块重新加载和美化打印。它们都是裸的顶层标准库函数,在任何宿主中都无需导入即可使用。`pretty` 和 `pretty-str` 是调试主力,也贯穿 集合 使用;`apply` 和 `curry` 扩展了 函数 中的可调用机制,而 `eval` 与 宏 搭配处理运行时代码。
## 函数
| 函数 | 用途 |
|---|---|
| `identity x` | 原样返回 `x` |
| `apply f args...` | 用显式参数(而非列表)调用 `f` |
| `curry f args...` | 部分应用 — 返回等待其余参数的闭包 |
| `eval code-string` | 求值一段 Deft 源码字符串 |
| `reload "path"` | 重新加载模块(无参数时重新加载当前命名空间的源码) |
| `pretty x indent?` | 将值美化打印到 stderr |
| `pretty-str x indent?` | 返回美化打印后的字符串 |
说明:
- `apply` 接受显式参数,而非列表:`[apply $add 4 5]`。`f` 可以是直接可调用对象(闭包、原生函数、关键字、映射、向量、集合),也可以是通过命名空间链解析的字符串/关键字名称,因此 `[apply "upper" "hello"]` 可用。关键字和映射充当访问器:`[apply :name %{ :name "Alice" }]` 返回 `"Alice"`。
- `curry` 固定前导参数并为其余参数返回闭包;`f` 在调用时解析,因此重定义会生效。`[curry str "Hello, "]` 可构建可复用的前缀函数。
- `eval` 返回最后一个表达式的值;源码为空时返回 `nil`。
- 不带参数的 `reload` 重新求值定义当前命名空间的文件;带路径时则在当前命名空间中求值该文件。现有 Var 单元就地更新,因此别处通过 `refer :all` 的引用会立即看到新值。成功时返回 `true`;没有源码路径或文件无法读取时返回 `nil`。
- `pretty` 将渲染后的值写入 stderr 并返回 `nil`;`pretty-str` 则返回字符串。两者默认使用 2 空格缩进;短集合保持一行,嵌套集合则展开。
## 示例
# identity — pass-through, useful as a default argument [identity 42] # => 42 # apply — explicit args; callables or resolved names def add {|a b| ($a + $b)} [apply $add 4 5] # => 9 [apply "upper" "hello"] # => "HELLO" [apply :name %{ :name "Alice" }] # => "Alice" # curry — fix leading args, get a closure for the rest def add5 [curry $add 5] [add5 10] # => 15 def greet [curry str "Hello, "] [greet "World"] # => "Hello, World" # eval — run source at runtime [eval "(1 + 2)"] # => 3 [eval "[str \"hi\" \"there\"]"] # => "hithere" # pretty vs pretty-str [pretty %{ :a 1 :b @{ "x" "y" } }] # rendered to stderr set text [pretty-str %{ :a 1 } 4] # string, 4-space indent # reload — pick up edits without a restart reload # current namespace's file [reload "apps/ants/ants.dft"] # a specific file