主要观点:介绍了学习科学研究所的程序员使用的一个真实宏的故事,展示了如何错误地设计和实现宏,以及my-wait-for
宏和wait-for
宏导致问题的原因和解决办法。
关键信息:
- 宏创建者是熟练的 Lisp 程序员,但设计的宏存在问题。
my-wait-for
从宏版本改为函数版本后,(my-wait-for 12)
不再等待,原因是宏和函数对(wait-for n)
的处理方式不同。wait-for
是宏,因其违反“一个函数对应一个功能”原则,导致调用格式易混淆。- 固定办法是创建两个等待形式,如
(wait-for *number*)
(函数)和(wait-until *expression*)
(宏),各自具有简单明确的语义。
重要细节: - 宏版本的
my-wait-for
将(my-wait-for 12)
展开为(wait-for 12)
,符合第一种调用格式。 - 函数版本的
my-wait-for
调用(wait-for n)
,n = 12
,符合第三种调用格式,即等待表达式n
为非 nil,但n
本身已非 nil,所以不等待。 (wait-for 12)
看似是函数调用并评估参数,实则根据参数形式决定做什么。- 改变
wait-for
评估参数的规则存在问题,如难以让程序员记住特殊处理数字的规则等。 - 合适的解决办法是创建两个不同的等待形式,避免语义混淆。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。