Lisp中的嵌套if

5

你好,我正在尝试在Lisp中创建一个嵌套的if语句,但是我们一直收到错误提示,不知道该如何修复!

** - EVAL: 特殊运算符IF的参数太多:

(defun spread-stones-helper(game-state StoneInHand Player player-index pit-index)

    ;; Do we have more stones in our hand?
   (if (> 0 StoneInHand)
        ;; Are we above the pit limit?
        (if (> pit-index 5)
            ;; Switch the player and reset the pit-index to 0
            (setq player-index (switchplayer player-index))
            (setq pit-index '0)
        )

        ;; Add 1 to the pit
        (set-pit game-state player-index (GetCorrectPit player-index pit-index) (+ (get-pit game-state player-index (GetCorrectPit player-index pit-index)) 1))

        ;; Recursive call the function, with one less stone and 1 up in pit-index
        (spread-stones-helper game-state (- StoneInHand 1) Player player-index (+ pit-index 1))
    )
    ;; There are no more stones in hand, run capture stones
    ;; (captureStones game-state StoneInHand Player player-index pit-index)
)

我认为你可能会因为你创建的奇怪的括号/缩进风格而感到困惑。 - Ken
3个回答

8
在Lisp中,if运算符接受三个表达式,分别是条件、条件为真时的值和条件为假时的值...例如:
(if (< x 0)
    (print "x is negative")
    (print "x is greater or equal than zero"))

您也可以省略最后一个表达式,此时它被认为是NIL。

如果您想在其中一个情况下放置更多的表达式,则必须将它们包装在progn表单中。

(if (< x 0)
    (progn
       (print "HEY!!!!")
       (print "The value of x is negative...")))

在IT技术领域,经常会出现只填写一个分支并使用多个表达式的if表达式的情况。因此,专门针对这种情况添加了两种特殊变体:

(when (< x 0)
    (do-this)
    (do-that)
    (do-even-that-other-thing))

(unless (< x 0)
    (do-this)
    (do-that)
    (do-even-that-other-thing))

上面的when表单等同于:
(if (< x 0)
   (progn
     (do-this)
     (do-that)
     (do-even-that-other-thing)))
unless形式的意义与其条件相反,换句话说它等价于...
(if (not (< x 0))
   (progn
     (do-this)
     (do-that)
     (do-even-that-other-thing)))

回顾一下,当你需要编写真假两个分支的代码时,应该只使用if。否则,根据测试的可读性,使用whenunless。在使用if形式时,如果需要放置多个表单,请在分支中使用progn

5
不要忘记使用(progn ...)来处理多个if语句。
(defun spread-stones-helper (game-state StoneInHand Player
                             player-index pit-index)

    ;; Do we have more stones in our hand?
   (if (> 0 StoneInHand)
       (progn
         ;; Are we above the pit limit?
         (if (> pit-index 5)
         (progn
               ;; Switch the player and reset the pit-index to 0
               (setq player-index (switchplayer player-index))
               (setq pit-index '0)))

         ;; Add 1 to the pit
         (set-pit game-state player-index
                  (GetCorrectPit player-index pit-index)
                  (+ (get-pit game-state player-index
                              (GetCorrectPit player-index pit-index))
                     1))

        ;; Recursive call the function, with one less stone and 1
        ;; up in pit-index
        (spread-stones-helper game-state
                              (- StoneInHand 1)
                              Player
                              player-index
                              (+ pit-index 1))))
   ;; There are no more stones in hand, run capture stones
   ;; (captureStones game-state StoneInHand Player player-index pit-index)
   )

5

"if"语句有一个测试和两个代码块-

你给第一个"if"语句提供了一个测试和三个代码块

假设(> 0 StoneInHand)为true。

你想运行第二个"if"语句和set-pit语句吗?

如果是这样,你需要将它们包裹在(progn )中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接