21

In C++ I'd write something like this:

if (a == something && b == anotherthing)
{
   foo();
}

Am I correct in thinking the Clojure equivalent is something like this:

(if (= a something)
    (if (= b anotherthing)
        (foo)))

Or is there another way to perform a logical "and" that I've missed? As I said the latter form seems to work correctly--I was just wondering if there's some simpler way to perform the logical and. And searching for "boolean" "logical" and "and" on the Clojure Google Group turned up too many results to be much use.

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
  • Please use standard indentation for Lisp code, and don't put closing parentheses on their own lines. May I edit that? – Svante Feb 11 '09 at 09:21
  • @Harleqin please feel free to fix this. I'm learning clojure and I would like to know established code formatting idioms. – Onorio Catenacci Feb 11 '09 at 10:38
  • Okay. Note that the sub-parts of the if statement line up. This is the usual way. For some constructs (mostly when you have a "body"), one just increases indentation by two spaces. I don't know whether there is a specific style guide for Clojure, but you can try to extrapolate from Common Lisp. – Svante Feb 11 '09 at 12:15
  • http://gigamonkeys.com/book/syntax-and-semantics.html -- Look at the part "Formatting Lisp Code" (towards the end). A good editor will help you with formatting; in fact, you can mostly see that you did something wrong when the automatic formatting doesn't meet your expectations. – Svante Feb 11 '09 at 12:18
  • @Harlequin--thanks for fixing up the code and thanks for the pointer to the formatting docs. – Onorio Catenacci Feb 11 '09 at 12:30

4 Answers4

35

In Common Lisp and Scheme

(and (= a something) (= b another) (foo))
Doug Currie
  • 40,708
  • 1
  • 95
  • 119
17

In Common Lisp, the following is also a common idiom:

(when (and (= a something) (= b another))
  (foo))

Compare this to Doug Currie's answer using (and ... (foo)). The semantics are the same, but depending on the return type of (foo), most Common Lisp programmers would prefer one over the other:

  • Use (and ... (foo)) in cases where (foo) returns a boolean.

  • Use (when (and ...) (foo)) in cases where (foo) returns an arbitrary result.

An exception that proves the rule is code where the programmer knows both idioms, but intentionally writes (and ... (foo)) anyway. :-)

David Lichteblau
  • 3,531
  • 2
  • 22
  • 12
8

In Clojure I would normally use something like:

(if 
  (and (= a something) (= b anotherthing))
  (foo))

It is clearly possible to be more concise (e.g. Doug's answer) but I think this approach is more natural for people to read - especially if future readers of the code have a C++ or Java background!

mikera
  • 105,238
  • 25
  • 256
  • 415
2

It's really cool! (and x y) is a macro -- you can check the source code at clojure.org -- that expands to (if x y false) equivalent to:

if (x) {
  if (y) {
    ...
  }
} else {
  false
}

(or x y) is similar but reversed.

Ralph
  • 31,584
  • 38
  • 145
  • 282