注意到了吗?这个命令和weld命令看起来好像!两条命令都需要检查位置,物体和对象!但是它们还是有不同,以至于我们不能将它们抽到一个函数里.太可惜了!
但是...这可是Lisp.我们不止能写函数,还能写SPEL!我们来创建了SPEL来处理:
(defspel game-action [command subj obj place & args]
`(defspel ~command [subject# object#]
`(spel-print (cond (and (= location '~'~place)
(= '~subject# '~'~subj)
(= '~object# '~'~obj)
(have? '~'~subj))
~@'~args
:else '(i cannot ~'~command like that -)))))
非常复杂的SPEL!它有很多怪异的quote,语法quote,逗号以及很多怪异的符号!更重要的是他是一个构建SPEL的SPEL!!即使是很有经验的Lisp程序员,也需要费下脑细胞才能写出这么个玩样!!(这里我们不管)
这个SPEL的只是向你展示,你是否够聪明来理解这么复杂的SPEL.而且,即使这段代码很丑陋,如果它只需要写一次,并且能生成几百个命令,那么也是可以接受的!
让我们使用这个新的SPEL来替换我们的weld命令:
(game-action weld chain bucket attic
(cond (and (have? 'bucket) (def chain-welded true))
'(the chain is now securely welded to the bucket -)
:else '(you do not have a bucket -)))
现在我们来看看这条命令变得多容易理解:game-action这个SPEL使得我们能编写我们想要的核心代码,而不需要额外的信息.这就像我们创建了我们自己的专门创建游戏命令的编程语言.使用SPEL创建伪语言称为领域特定语言编程(DSL),它使得你的编码更加的快捷优美!
(weld chain bucket)user=> (weld chain bucket)
(you do not have a chain -)
...我们还没有做好焊接前的准备工作,但是这条命令生效了!
下面我们重写dunk命令:
(game-action dunk bucket well garden
(cond chain-welded
(do (def bucket-filled true)
'(the bucket is now full of water))
:else '(the water level is too low to reach -)))
注意weld命令需要检验我们是否有物体,但是dunk不需要.我们的game-action这个SPEL使得这段代码易写易读.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shumachanpin/article-41579-7.html
哈哈哈哈哈哈哈哈哈
少了100