2

大家好,简单的问题...

使用 XLISP 编写程序,但我似乎遇到了一个我似乎无法解决的简单基本问题:也许有人有一个快速修复。

我正在尝试编写一个 if 语句,该语句的 then 子句评估多个表单并返回最后一个的值。

例如:

(setq POSITION 'DINING-ROOM)

(defun LOOK (DIRECTION ROOM) ... )
(defun SETPOS (ROOM) ... )
(defun WHERE () ... )

(defun MOVE (DIRECTION)
(if (not(equal nil (LOOK DIRECTION POSITION))) ; If there is a room in that direction
( ; Then-block: Go to that room. Return where you are.
(SETPOS (LOOK DIRECTION ROOM))
(WHERE)
)
( ; Else-block: Return error
(list 'CANT 'GO 'THERE)
)
)

预期的逻辑等价物是:

function Move (Direction)
{

if(Look(Direction, Room) != null)
{
SetPos(Look(Direction,Room));
return Where();
}
else
{
return "Can't go there";
}

}

(为糟糕的网络格式道歉。)

我遇到的问题是:

(
(SETPOS (LOOK DIRECTION ROOM))
(WHERE)
)

我只是想返回 WHERE 的评估,但我需要先执行 SETPOS 函数。XLISP 不喜欢多余的括号:如果我删除了外部集合,我的 WHERE 列表就变成了我的 else(我不想要那个)。如果我删除 SETPOS 和 WHERE 周围的集合,它会将 WHERE 视为 SETPOS 的参数;我也不想要那个。

那么,我如何简单地评估第一个,然后是第二个,然后返回最后一个评估的值?

4

2 回答 2

3

Lisp 通常提供类似 PROGN 的东西。PROGN 计算一系列表达式并返回最后一个表达式的值。

(progn
  (do-this)
  (do-that))

另请查看您的代码:

(if (not(equal nil (LOOK DIRECTION POSITION)))

(EQUAL NIL (FOO))  is the same as  (NULL FOO)

(NOT (NULL FOO)) is the same as FOO.

所以你可以简单地写:

(if (LOOK DIRECTION POSITION) ... ...)

或者如果你想检查是否有房间:

(if (ROOM-P (LOOK DIRECTION POSITION)) ... ...)

ROOM-P 将是一个谓词,如果某物是房间,则返回 T。

您可能还想使用典型的 Lisp 缩进:

(defun MOVE (DIRECTION)
  (if (LOOK DIRECTION POSITION)
    (progn
      (SETPOS (LOOK DIRECTION ROOM))
      (WHERE))
    (progn
      ...
      (list 'CANT 'GO 'THERE))))

还有一个 COND 构造:

(defun MOVE (DIRECTION)
  (cond ((LOOK DIRECTION POSITION)
         (SETPOS (LOOK DIRECTION ROOM))
         (WHERE))
        (t
         ...
         (list 'CANT 'GO 'THERE))))

我还建议从 XLISP 切换到 CLISP 或 ECL 之类的东西。XLISP 很旧,大部分都没有维护,也不是 Common Lisp。

于 2010-05-21T13:10:02.857 回答
1

所以我找到了一种连续执行的方法(无论它是否是最好的方法):

改变:

(
(SETPOS (LOOK DIRECTION ROOM))
(WHERE)
)

至:

(let ()
(SETPOS (LOOK DIRECTION ROOM))
(WHERE)
)

它执行了两种形式并返回了最后一种形式的输出。

于 2010-05-20T22:31:50.863 回答