Почему не делает (подайте заявку или [истинная ложь]), работа в Clojure?

Из того, что я понимаю о, применяются, это распаковывает список и превращает элементы в аргументы в пользу функции.

Я вижу что (применяются + [1 2 3]), работы как ожидалось, т.е.: это эквивалентно (+ 1 2 3).

Почему затем (подайте заявку или [истинная ложь]), недопустимый? Разве это не эквивалентно (или истинная ложь)?

20
задан Tachy 3 June 2010 в 20:31
поделиться

5 ответов

Потому что или - это макрос, а не обычная функция. Вы можете получить тот же эффект с (некоторая идентичность [true false]) .

20
ответ дан 30 November 2019 в 00:43
поделиться

Можно попробовать с истиной? а ложь? предикаты,


user=> (some true? [true false false])
true
user=> (not (some true? [true false false]))
false
user=> (some false? [true false false])
true
user=> (not (some false? [true false false]))
false

3
ответ дан 30 November 2019 в 00:43
поделиться

or - это макрос, который вы не можете использовать в качестве значения.

Создайте анонимную функцию, расширяющую or во время выполнения через eval:

(apply #(eval (list* 'or %&)) [true false])
0
ответ дан 30 November 2019 в 00:43
поделиться

В качестве альтернативы или вы можете использовать (some predicate coll).

clojure.core/some ([pred coll])
Возвращает первое логически истинное значение (pred x) для любого x в coll, иначе nil. Одной из распространенных идиом является использование множества в качестве pred, например возвращает :fred, если :fred находится в последовательности, иначе nil: (some #{:fred} coll)

5
ответ дан 30 November 2019 в 00:43
поделиться

Одна из важных вещей, на которые следует обратить внимание, - это модель оценки. или замыкаются, поэтому: (или истина: какое-то случайное выражение, которое никогда не вычисляется:) никогда не оценивает последнее. или традиционно используется в качестве управляющей структуры как «логическое ИЛИ».

В традиционной модели (f x y z) вычисляются x, y и z, и к ним применяется f.

При использовании (применить f vec) содержимое вектора не оценивается, оно принимается как есть. Это наиболее четко видно с вектором символов, они не оценивают в этом контексте свои привязки. Однако это запутывается тем фактом, что модель создания вектора в Clojure несколько отличается от других шепелявых: [abcd] дает вектор, который содержит оценки символов a , b , c и d . В отличие от большинства Лиспов, где # (abcd) не оценивает символы, а просто идентично вычислению (вектор 'a' b 'c' d) (или фактически ] (применить вектор '(abcd)) ).

Таким образом, даже если бы можно было применять специальные синтаксические формы, результат имел бы непрозрачную семантику. или сначала оценивает свой первый аргумент, если он истинен, он останавливается и возвращает его, иначе он переходит ко второму и повторяется до последнего.В случае применения, все аргументы уже оценены, следует ли затем оценивать некоторые во второй раз? Скорее всего, это приведет к ошибке во время выполнения?

С точки зрения реализации, было бы очень плохо, если бы синтаксис был также «объектами» и потребовал бы гораздо более сложной модели оценки. Таким образом, они не разрешаются во время выполнения, а, скорее, переписываются в примитивы компилятора во время компиляции.

Но именно по этой причине, когда или используются логически, а не как управляющая структура, я сам считаю удобным иметь функции или / f , и Доступны / f , if / f и т. д., которые являются истинными процедурами и оценивают все их аргументы и, таким образом, могут применяться.

0
ответ дан 30 November 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: