先看看自定义函数ifbefore((defineif(lambda(pthen_velse_v)((or(andpcar)cdr)(consthen_velse_v))))(if(quote(>12))(3)(cons24)))看起来没问题,但是因为它会在涉及输入参数绑定值时评估传入的s-expression值,if涉及到递归,就会有问题,所以我们需要加引号,但是这样也会带来新的问题如果我们要延迟对传入的s表达式的求值,就需要修改每个表达式,无疑增加了很多脑力负担,如何减轻负担?我们的期望我们的表达式变成了这样:(if(>12)3(cons24))首先,我们想到的是将上面的表达式展开后的预期效果是什么?((or(and(>12)car)cdr)(cons3(cons24)))这时候我们可以使用apply函数来实现。在开始之前,我们首先转换if函数then_velse_v)))))这时候我们可以使用apply函数来调用,apply函数的作用是函数调用时,当最后一个参数是列表或者引用时会被压平如下(applyif(`((>12)3(cons24))))=>((or(and(>12)car)cdr)(cons3(cons24)))等同于(if(`(>12))(`3)(`(cons24)))=>((or(and(>12)car)cdr)(cons3(cons24)))他们都会输出我们期望的化合物列表。这个时候我们只需要再调用一次,比如(apply(applyif(`((>12)3(cons24)))))细心的你已经发现我们在定义if函数的时候用了很多list函数和quote函数。好像很麻烦。这里我们使用一种简化的写法(defineif(lambda(pthen_velse_v)(`((or(and,pcar)cdr)(cons,then,else)))))如果引用类型中有,符号的下一个元素将被评估,否则将被忽略核心是两个应用。首先,执行第二个apply会得到表达式。第一个将获取表达式并调用它以获得最终值。(apply(applyif(`((>12)3(cons24)))))核心就是把这段的pattern写成这样(apply(applyexp(`exp)))然后我们封装代码如下:privatestaticObjectdefineMacro(ApplyArgsapplyArgs){Conscdr=applyArgs.getExp();validateTrue(applyArgs.getEnv().noContains(cdr.carSymbols()),"不要重复定义"+cdr.carSymbols());Function
