2

皆さん、素朴な疑問...

XLISP を使用してプログラムを作成していますが、回避できない単純な根本的な問題に遭遇したようです。おそらく誰かが簡単に修正します。

then-clause が複数のフォームを評価し、最後の値を返す 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";
}

}

(Web フォーマットが貧弱で申し訳ありません。)

私が抱えている問題は次のとおりです。

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

単純に WHERE の評価を返したいのですが、最初に SETPOS 関数を実行する必要があります。XLISP は余分な括弧が好きではありません: 外側のセットを削除すると、私の WHERE リストは私の else になります (私はそれを望んでいません)。SETPOS と WHERE の前後のセットを削除すると、WHERE が SETPOS の引数のように扱われます。私もそれはしたくない。

では、最初の評価、次に 2 番目の評価を行い、最後に評価された値を返すにはどうすればよいでしょうか。

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 に答える