16

In elisp, the if statement logic only allows me an if case and else case.

(if (< 3 5) 
  ; if case
    (foo)
  ; else case
    (bar))

but what if I want to do an else-if? Do I need to put a new if statement inside the else case? It just seems a little messy.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Cameron
  • 2,805
  • 3
  • 31
  • 45

1 Answers1

35

Nesting if

Since the parts of (if test-expression then-expression else-expression) an else if would be to nest a new if as the else-expression:

(if test-expression1
    then-expression1
    (if test-expression2
        then-expression2
        else-expression2))

Using cond

In other languages the else if is usually on the same level. In lisps we have cond for that. Here is the exact same with a cond:

(cond (test-expression1 then-expression1)
      (test-expression2 then-expression2)
      (t else-expression2))

Note that an expression can be just that. Any expression so often these are like (some-test-p some-variable) and the other expressions usually are too. It's very seldom they are just single symbols to be evaluated but it can be for very simple conditionals.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
  • 1
    I would say that "use `cond`" is probably the most idiomatic solution. Sometimes, things are clearer with nested ifs, but that is so seldom that "use `cond`" is a sensible first approach. – Vatine Dec 06 '16 at 14:51
  • @Vatine I agree as long as the if tree is heavy on one branch. If you have something like this `(if (red? o) (if (square? o) 'red-square 'red-round) (if (square? o) 'blue-square 'blue-round))` you get away with far less tests than `(cond ((and (red? o) (square? o)) 'red-square) ((red? o) 'red-round) ((square? o) 'blue-square) (t 'blue-round))`. For an average of 3.25 tests per time vs 2 and with the `cond` the code is slightly more messy to follow. I never use `cond` if I don't use any of the extra features over `if`. eg. `(if test then else)` I never write as `cond` – Sylwester Dec 06 '16 at 15:23
  • Yep, one of the reasons why I didn't said "never use it". There are times when nested `if` (or multiple `when`, wrapped in an `or`, with `if` inside) is clearer than a `cond`. – Vatine Dec 06 '16 at 16:08