Подтвердить что ты не робот

Эквивалент Clojure (или Lisp) сложного булева теста

В С++ я бы написал что-то вроде этого:

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

Я правильно понимаю, что эквивалент Clojure выглядит примерно так:

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

Или существует другой способ выполнить логическое "и", которое я пропустил? Как я уже сказал, последняя форма работает корректно - мне просто интересно, есть ли какой-нибудь более простой способ выполнить логическое и. И поиск "логических" "логических" и "и" в Clojure Группе Google показал слишком много результатов, чтобы их было много использовать.

4b9b3361

Ответ 1

В общем Lisp и схеме

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

Ответ 2

В Common Lisp также распространена идиома:

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

Сравните это с ответом Дуга Керри, используя (and ... (foo)). Семантика одна и та же, но в зависимости от типа возврата (foo) большинство Common Lisp программистов предпочли бы один над другим:

  • Используйте (and ... (foo)) в случаях, когда (foo) возвращает логическое значение.

  • Используйте (when (and ...) (foo)) в случаях, когда (foo) возвращает произвольный результат.

Исключением, которое доказывает правило, является код, в котором программист знает обе идиомы, но намеренно пишет (and ... (foo)) в любом случае.: -)

Ответ 3

В Clojure я бы обычно использовал что-то вроде:

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

Очевидно, что можно быть более кратким (например, ответ Дуга), но я думаю, что этот подход более естественен для людей, чтобы читать - особенно если будущие читатели кода имеют фон С++ или Java!

Ответ 4

Это действительно здорово! (and x y) - макрос - вы можете проверить исходный код в clojure.org - который расширяется до (if x y false), эквивалентного:

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

(or x y) аналогичен, но наоборот.