Последовательные звонки / оценки в форме? - PullRequest
2 голосов
/ 21 мая 2010

Эй, ребята, простой вопрос ...

Работа с XLISP для написания программы, но я, кажется, столкнулся с простой фундаментальной проблемой, с которой не могу обойтись: возможно, у кого-то есть быстрое решение.

Я пытаюсь написать оператор if, который в последующем выражении оценивает несколько форм и возвращает значение последней.

Например:

(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; Я тоже этого не хочу.

Итак, как мне просто оценить первое, затем второе и затем вернуть значения последнего оцененного?

Ответы [ 2 ]

3 голосов
/ 21 мая 2010

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.

1 голос
/ 21 мая 2010

Итак, я нашел способ выполнять последовательные казни (наилучшее из них или нет):

Изменено:

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

Кому:

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

Который выполнил обе формы и возвратил вывод последней.

...