Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions devel/216_48.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# [216_48] 为 liii/cut 添加文档和测试用例

## 任务相关的代码文件
- goldfish/liii/cut.scm
- tests/goldfish/liii/cut-test.scm
- tests/liii/cut-test.scm(新建)

## 如何测试
```
xmake config --yes
xmake b goldfish
bin/gf fix tests/liii/cut-test.scm
bin/gf tests/liii/cut-test.scm
```

## 如何查看文档
使用 `gf doc` 命令查看 cut 模块的文档:
```
bin/gf doc liii/cut
```

## 2026/04/03 为 liii/cut 添加文档和测试用例(已完成)

### What
为 `(liii cut)` 模块添加文档,使 `bin/gf doc liii/cut` 能够显示对 AI 编程有帮助的文档和测试用例。

1. 新建 `tests/liii/cut-test.scm` 文件,包含文档注释和测试用例
2. 文档内容包括:
- 模块功能说明(SRFI-26 的 cut/cute 宏,用于创建部分应用函数)
- 常见用法示例(含占位符 `<>` 和可变参数 `<...>` 的使用)
- `cut` 与 `cute` 的区别(运行时求值 vs 创建时求值)
- 函数分类索引

### Why
- `bin/gf doc liii/cut` 目前显示 "No documentation and test cases available"
- 需要为 AI 编程提供清晰的 cut/cute 使用指南
- cut 是函数式编程中常用的部分应用工具,对 AI 生成代码很有帮助

### How
1. 在 `tests/liii/` 目录下新建 `cut-test.scm` 文件(`gf doc` 命令从此目录提取文档)
2. 文件头部使用 `;;` 注释添加文档说明,格式参考 `tests/liii/argparse-test.scm`
3. 包含以下内容:
- 模块用途说明
- 占位符语法:`<>` 表示单个参数位置,`<...>` 表示可变参数
- cut vs cute 的区别说明
- 典型使用场景示例
- 函数分类索引

### 验证结果
- 测试全部通过:19 correct, 0 failed
- `bin/gf doc liii/cut` 成功显示完整文档和测试用例
54 changes: 0 additions & 54 deletions tests/goldfish/liii/cut-test.scm

This file was deleted.

109 changes: 109 additions & 0 deletions tests/liii/cut-test.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
;; (liii cut) 模块测试文件
;;
;; cut 和 cute 是 SRFI-26 提供的宏,用于创建部分应用(Partial Application)函数。
;; 它们允许你预先填充函数的部分参数,留下一些参数位置待后续传入。
;;
;; 核心用途:在不使用 lambda 的情况下快速创建函数闭包,适用于函数式编程中的参数预设。

;; ==== 语法说明 ====
;;
;; (cut <函数> <参数>...)
;; - 创建一个新函数,<函数> 会被延迟到调用时执行
;; - <> 表示单个参数占位符(slot),调用时按顺序填充
;; - <...> 表示可变参数占位符(rest-slot),收集剩余所有参数
Comment on lines +9 to +13
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 语法描述未涵盖无参数形式 (cut)

文档将 cut 的语法写成 (cut <函数> <参数>...),暗示至少需要一个"函数"参数。但测试用例第 85 行中 ((cut)) => () 表明 (cut) 在不传任何参数时也是合法的(符合 SRFI-26 规范)。

建议在语法说明中补充零参数情况,或注明 <函数> 也可以省略,以避免读者产生 (cut) 为非法语法的误解。

;;
;; (cute <函数> <参数>...)
;; - 与 cut 类似,但参数在创建时立即求值(非调用时)
;; - 适用于参数包含副作用(如 set!)的场景

;; ==== 常见用法示例 ====
;;
;; 示例1:预设函数的第一个参数
;; ((cut + 10 <>) 5) => 15
;;
;; 示例2:预设函数的中间参数
;; ((cut list 'a <> 'c) 'b) => (a b c)
;;
;; 示例3:使用多个占位符
;; ((cut list <> <>) 'x 'y) => (x y)
;;
;; 示例4:结合可变参数
;; ((cut + 1 <...>) 2 3 4) => 10
;; ((cut <> 1 <...>) + 2 3) => 6
;;
;; 示例5:将占位符作为函数位置
;; ((cut <> 'arg) procedure?) => 检查 'arg 是否是过程

;; ==== cut vs cute 的区别 ====
;;
;; cut: 参数在调用时才求值
;; (let ((a 1))
;; (define f (cut + a <>))
;; (set! a 10)
;; (f 5)) => 15 (使用 a 的当前值 10)
;;
;; cute: 参数在创建时就求值
;; (let ((a 1))
;; (define f (cute + a <>))
;; (set! a 10)
;; (f 5)) => 6 (使用 a 创建时的值 1)

;; ==== 使用场景 ====
;;
;; 1. 快速创建单参数函数传递给 map/filter
;; (map (cut * 2 <>) '(1 2 3)) => (2 4 6)
;;
;; 2. 预设回调函数的上下文参数
;; (button :on-click (cut handle-click 'save))
;;
;; 3. 构建函数管道中的中间转换器
;; (compose (cut string-append "prefix-" <>) number->string)

;; ==== 函数分类索引 ====

;; 一、部分应用宏
;; cut - 延迟求值的部分应用(参数在调用时求值)
;; cute - 立即求值的部分应用(参数在创建时求值)

;; ==== 单元测试 ====

(import (liii check)
(liii cut)
) ;import

(check-set-mode! 'report-failed)

;; 基础占位符测试
(check ((cut list <> 'y <>) 'x 'z) => '(x y z))
(check ((cut + 1 <...>) 2 3) => 6)
(check ((cut + 1 <...>)) => 1)
(check ((cut <> 1 <...>) + 2 3) => 6)
(check ((cut list <> <> <...>) 1 2 3) => '(1 2 3))
(check ((cut list <> <> <...>) 1 2) => '(1 2))
(check ((cut + 1 2)) => 3)
(check ((cut <>) list) => ())
(check ((cut)) => ())
(check ((cut <> #t <...>) if 1 0) => 1)

;; 错误处理测试
(check-catch 'wrong-number-of-args ((cut list <> <>) 1))
(check-catch 'wrong-number-of-args ((cut list <> <> <...>) 1))
(check-catch 'syntax-error ((cut list <> <> <...> <>) 1 2 3))

;; cut vs cute 求值时机对比测试
(let* ((a 1)
(f (cut <> (set! a 2))))
(check a => 1)
(check (f (lambda (x) x)) => 2)
(check a => 2)
) ;let*

(let* ((a 1)
(f (cute <> (set! a 2))))
(check a => 2)
(set! a 1)
(check (f (lambda (x) x)) => 2)
(check a => 1)
) ;let*

(check-report)
Loading