clisp:变量x没有值

时间:2014-04-27 20:23:56

标签: lisp common-lisp clisp

我在Common Lisp代码中收到错误variable MAP has no value(我在Ubuntu终端中使用了clisp shell)。我的代码看起来像这样(*map*只是一个关联列表,所以你可以跳过它):

(setf *map* '((shore (stars cast reflections on the rippling sea.  
                            it fills you with a strong but unplaceable emotion.) 
                     (east forest))
              (forest (a roof of treetops blots out the sun.  something rustles 
                         behind you.) 
                      (west shore) 
                      (north cliff))
              (cliff (you nearly stumble into a long and fatal fall into the 
                          sea far below you.  you feel a strange urge to throw 
                          yourself off the ledge.  it would probably wisest to 
                          leave this place.) 
                     (south forest))))

(defun walk-direction (direction room map)
  (second (assoc direction (cddr (assoc room map)))))

(defmacro defspel (&rest rest) `(defmacro ,@rest))

(defspel walk-to (direction room map)
  `(walk-direction ',direction ',room map))

(walk-to east shore *map*)

(我正在关注liserpati教程,对于那些对我可能犯下的任何奇怪事情感到疑惑的人)

如果改变步行到

(defspel walk-to (direction room)
  `(walk-direction ',direction ',room *map*))
然后一切都很顺利。然而,这打破了函数式编程的美妙惯例,我希望尽可能保持完整 - 更不用说我仍然不知道为什么我的代码不起作用。

2 个答案:

答案 0 :(得分:6)

walk-to的定义在map之前缺少逗号。看看输出:

(macroexpand-1 '(walk-to east shore *map*))

答案 1 :(得分:0)

我们来看看:

(defspel walk-to (direction room map)
  `(walk-direction ',direction ',room map))

这里,符号映射在反引号内,并且不是不引用的。这意味着它只是一个文字数据。它与map法术的walk-to参数无关。

生成的walk-direction代码在map参数不再可见的环境中进行评估;它被视为一个自由变量引用,它需要一个全局变量。

当您将map更改为*map*时,您可以解决部分问题;然后,生成的代码引用全局环境中的动态变量*map*

但是这仍然被打破,因为walk-to应该生成使用传入的map的代码,这不一定是全局地图(或者为什么有参数)。 / p>

你可能想要这个:

(defspel walk-to (direction room map)
  `(walk-direction ',direction ',room ,map))

因此,例如,调用(walk-to north shore *map*)将生成代码(walk-direction 'north 'shore *map*)walk-to宏为你引用方向和房间符号,但不应引用*map*,因为那是我们需要评估它所代表的地图对象的Lisp变量,而不是{{1}这样的游戏符号{1}}。