HTDP 学习博客
发布: (2025年12月31日 GMT+8 10:32)
5 min read
原文: Dev.to
Source: Dev.to
这篇博客是从大量往年试题(2019–2024)和 HTDP / Racket 课堂规则中提炼出的综合学习指南。它侧重于求值、函数设计、数据驱动模板、递归、抽象、局部作用域/闭包以及常见的考试陷阱。
作者说明
本博客摘自日常笔记和复习时的错误汇总,唯一目的在于帮助编写清晰、可读、易于协作的代码,并理解 Racket 程序的底层执行模型。它 不 包含三章侧重算法的内容(如图、累加器和搜索)。对于这些章节,最重要的建议是:自行通读历年试卷。后续将另开博客专门讲解 HTDP 中的算法内容。
评估问题(逐步约简)
核心规则
- 一次性替换所有参数。
- 对由
define定义的常量逐个替换,按顺序进行。 - 对
cond,先约简条件,然后评估所选分支。 - 对
or,第一个为真的值会停止求值。 - 始终运行程序以确认最终值。
函数调试问题
常见修复
- 谓词函数必须以
?结尾。
常见错误
- 选择器中的坐标被交换。
HTDD (如何设计数据)
规则
cond中的最后一个条件应使用else。
HTDW(World Programs)
关键事件
- 使用
cond根据键值处理键事件,最后的else情况返回未改变的世界。
提示
- 渲染函数必须在
big-bang之前定义。
参考与递归问题
自引用 vs. 相互引用
- 自递归:函数调用自身。
信任自然递归
- 一旦第一个元素正确,信任其余部分。
空基例 (非常重要)
- 空列表的求和返回
0。
抽象和高阶函数
选择合适的抽象函数
- 当目标是 生成 列表时使用
map或filter。 - 当目标是 聚合 值时使用
foldr或foldl。 - 当基于索引生成列表时使用
build-list。
函数签名
map:(X → Y) → (Listof X) → (Listof Y)filter:(X → Boolean) → (Listof X) → (Listof X)foldr:(X Y → Y) → Y → (Listof X) → Ybuild-list:Natural → (Natural → X) → (Listof X)
常见错误
- 不要 在把函数作为参数传递时调用它。
本地、闭包与提升
闭包定义
如果满足以下条件,则函数是闭包:
- 它是一个函数。
- 它使用了参数列表中未列出的变量。
- 这些变量来自外部作用域。
评估成本
- 循环外的定义会被评估 一次。
- 循环内的定义会在 每次迭代 时评估。
Genrec(生成递归)
必须包含
- 基础情况。
- 简化步骤。
- 终止论证。
常见错误
- 错误的基础情况会导致图像或数值不正确。
良好结构的数据定义
- 非良好结构:(错误定义的示例)
- 良好结构:(正确定义的示例)
Helper Functions — When Are They Needed?
使用帮助函数的情形包括:
- 引用非原始类型的嵌套数据。
- 执行两阶段处理。
- 切换知识领域。
- 处理任意大小的数据结构,如列表或树。
参数 vs. 实参 vs. 操作数
- 参数:函数定义中的名称。
- 实参:在调用处提供的实际值。
- 操作数:运算符作用的值(例如
+中的两个数字)。
考试生存清单
- 严格遵循模板。
最终建议
正确设计,然后信任递归。HTDP 考试奖励纪律、模板和精确——而不是巧妙的技巧。作为初学者,我通过学习这些基本的设计原则并在未来的编程中加以扩展,感到非常有成就感,成为一个行为良好且合作的程序员。