Одна из важных вещей, чтобы отметить, хотя это модель оценки. or
короткое замыкание, поэтому: (or true :some random expression that never gets evaluated:)
никогда не оценивает последнее. or
традиционно используется как структура управления как «логическая» или «логическая».
В традиционной модели (f x y z)
оцениваются x, y и z, а f применяется к ним.
При использовании (apply f vec)
содержание вектора не оценено, они взяты как есть. Это наиболее четко видно с помощью вектора символов, они не оценивают в этом контексте их привязки. Тем не менее, это запутывается тем фактом, что модель Клоджуре для создания вектора - это нечто иное, чем другие листки, [a b c d]
дает вектор, который содержит оценки символов a
, b
, c
и d
. Контрастность большинства Lisps, где #(a b c d)
не оценивает символы и просто идентична оценке (vector 'a 'b 'c 'd)
(или фактически (apply vector '(a b c d))
).
Так что, даже если бы можно было применять специальные синтаксические формы, результат был бы непрозрачной семантикой. or
сначала оценивает свой первый аргумент, если true, он останавливается и возвращает это, иначе он переходит ко второму и повторяется до последнего. В случае применения аргументы уже оцениваются, если они затем оценивают второй раз? Скорее всего, это приводит к ошибке во время выполнения?
С точки зрения реализации, это было бы очень выгодно, если бы синтаксис был также «объектами» и требовал бы гораздо более сложной оценочной модели. Таким образом, они не разрешаются во время выполнения, а скорее переписываются компилятору во время компиляции.
Но, по этой причине, когда or
используется логически, а не в качестве структуры управления, я сам нахожу это удобно иметь функции or/f
, and/f
, if/f
и так далее доступны, которые являются истинными процедуры и оценить все их аргументы и, следовательно, может применяться.
Ах. Благодаря! Можете ли вы придумать какие-либо альтернативы? – TriArc
'(уменьшить # (или% 1% 2) false [true false ...])' –
Я думал, что 'some' был' (первый фильтр) 'сам, пока Chouser любезно заставил меня увидеть более сложную реальность. Попробуйте '(некоторые: a [{: a false} {: a nil} {: a true}]), а затем замените' some' на '(comp first filter)'. –