Clojureで機能しないのはなぜですか([True False]を適用または[True False])機能させませんか?

StackOverflow https://stackoverflow.com/questions/2969543

  •  24-10-2019
  •  | 
  •  

質問

私がApplyについて理解していることから、それはリストを開梱し、要素を関数の引数に変えます。

(apply + [1 2 3])が期待どおりに機能すること、つまり( + 1 2 3)に相当することがわかります。

なぜ(適用または[true false])無効なのですか?それは同等ではありません(または真の偽)?

役に立ちましたか?

解決

なぜなら or マクロであり、通常の関数ではありません。同じ効果を得ることができます (some identity [true false]).

他のヒント

代替手段として また 使用できます(いくつか 述語coll)。

clojure.core/some([pred coll])
collのxの最初の論理真の値(pred x)を返します。 1つの一般的なイディオムは、セットをPredとして使用することです。たとえば、これは戻ります。Fredif:Fredがシーケンスにあり、そうでなければnil:(some#{:fred} coll)

あなたは本当のことでいくつかを試すことができますか?と偽?述語、


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

また マクロであり、価値として使用できません。

匿名関数を作成し、拡大します またランタイム 評価経由:

(apply #(eval (list* 'or %&)) [true false])

注意すべき重要なことの1つは、評価モデルです。 or したがって、短絡、したがって: (or true :some random expression that never gets evaluated:) 最後を評価しないでください。 or 従来、制御構造と同じくらい「論理的または」と同じくらい使用されています。

の伝統的なモデルで (f x y z), 、x、y、zを評価し、fがそれらに適用されます。

の使用で (apply f vec) ベクトルの内容はです いいえ 評価されて、それらはそのままと考えられます。これは、シンボルのベクトルで最もはっきりと表示されます。このコンテキストでは、バインディングを評価しません。ただし、これは、ベクターの作成のためのClojureのモデルが他のLISPよりも何らかの異なるという事実によって難読化されています。 [a b c d] シンボルの評価を含むベクトルを生成します a, b, c, 、 と d. 。ほとんどのLISPは対照的です #(a b c d) シンボルを評価せず、評価するのと同じです (vector 'a 'b 'c 'd) (または実際に (apply vector '(a b c d))).

したがって、特別な構文フォームを適用できたとしても、結果は不透明なセマンティクスがあります。 or 最初に最初の引数を評価します。もし真であれば、それは停止してそれを返します。応募の場合、引数はすべて評価されていますが、2回目の評価を行う必要がありますか?途中でランタイムエラーが発生する可能性が最も高いですか?

実装の観点から見ると、構文が「オブジェクト」でもあり、はるかに複雑な評価モデルが必要な場合、非常にパフォーマンスが非常に活発になります。そのため、実行時に解決されるのではなく、コンパイル時にコンパイラプリミティブに書き直されます。

しかし、この理由で、いつ or 制御構造としてではなく論理的に使用されています、私自身は関数を持っているのが便利だと思います or/f, and/f, if/f, 、真の手順であり、それらのすべての議論を評価し、したがって適用できるET CETETERA。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top