Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested if in lisp

Tags:

lisp

Hello i am trying to create a nested if in lisp, but we keep getting the error, and we don't know how to fix it!

** - EVAL: too many parameters for special operator 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)
)
like image 357
Androme Avatar asked Oct 12 '11 20:10

Androme


2 Answers

In lisp the if operator accepts three expressions that are the condition, value in case the condition is true and value when the condition is false... for example

(if (< x 0)
    (print "x is negative")
    (print "x is greater or equal than zero"))

You can also omit the last expression and in this case it's assumed to be NIL.

If you want to put more expressions in one of the two cases you must wrap them in a progn form

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

The case of having an if expression with only one of the two branches filled and with many expressions was found to be very frequent and therefore two special variations for this exact use were added:

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

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

The when form above is equivalent to

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

The unless form has the very same meaning but with the condition reversed... in other words it's equivalent to

(if (not (< x 0))
   (progn
     (do-this)
     (do-that)
     (do-even-that-other-thing)))

To recap you should use if only when you need to write code for both branches (the true and the false one). Otherwise use either when or unless depending on what is more readable for your test.

When using an if form you must use a progn in branches where you need to put more than a single form.

like image 127
6502 Avatar answered Nov 09 '22 16:11

6502


"if" takes a test and two forms -

You've given the first "if" a test and three forms

Assume (> 0 StoneInHand) is true.

Do you want to run both the second if and the set-pit statements?

If so, you need to wrap them in a (progn )

like image 24
user992214 Avatar answered Nov 09 '22 18:11

user992214