Clojure中的逻辑真实性

时间:2015-07-15 01:30:23

标签: clojure

true?实际上说了什么? (true? 0) = false(if 0 "0 is true" "0 is false") = 0 is true。 为什么会这样?

3 个答案:

答案 0 :(得分:4)

在Clojure中,nilfalse被视为“false”,其他所有内容都被视为true,这解释了问题中if表达式的行为。

另一方面,仅当提供true值时,true?谓词才为true

有关更多信息,请查看此article讨论Clojure中的Truthy和Falsey概念。

答案 1 :(得分:3)

你混淆了两件事:

  • Clojure中的不同
  • intent.addCategory(Intent.CATEGORY_LAUNCHER);及其后代对待这些价值观的方式。

iftrue是值,它们是不同的:

1

但它们与(= true 1) ; false 的第一个参数具有相同的效果:

if

事实上,几乎任何第一个参数都会导致(if true "Hello!" "Goodbye.") ; "Hello!" (if 1 "Hello!" "Goodbye.") ; "Hello!" 评估并返回其第二个参数:

if

只有两个导致(if + "Hello!" "Goodbye.") ; "Hello!" (if *ns* "Hello!" "Goodbye.") ; "Hello!" (if String "Hello!" "Goodbye.") ; "Hello!" 评估并返回其第三个​​参数。这两个值为iffalse

nil

如果没有提供第三个参数,则默认为(if false "Hello!" "Goodbye.") ; "Goodbye." (if nil "Hello!" "Goodbye.") ; "Goodbye."

nil

值之间的相同区别适用于其他Clojure条件,它们直接或间接来自(if false "Hello!") ; nil ifif-notwhen,{{ 1}},when-not,& c。它们表示为宏,因此,与and一样,它们不会在需要之前评估它们的参数。

引用official documentation

  

(如果是其他测试?)

     

评估or。如果不是单数值iftest,则评估并生成nil,否则,评估   和收益率false。如果未提供then,则默认为else。所有   Clojure中其他条件的基于相同的逻辑,   也就是说,elsenil构成了逻辑虚假和一切   否则构成逻辑真理,这些意义贯穿始终。

答案 2 :(得分:0)

除了给出的答案,还有一些测试代码!

; a simple way to define two functions that give the "truthy" or "falsey"
; value as an actual boolean (i.e. either the value 'true' or the value
; 'false' for an arbitrary Clojure 'thing'. These functions are _total_
; (i.e. defined for everything and never raise exceptions or return nil)

(defn truthy? [x] (if x true false))
(defn falsey? [x] (if x false true))

; Some test code
; https://clojure.github.io/clojure/clojure.test-api.html

(require '( clojure test ))

; clojure.test/is checks whether the value it is given is "truthy", not
; whether it is equal to the boolean 'true'!

(clojure.test/is true)  ; passes 
(clojure.test/is 1)     ; passes
(clojure.test/is 0)     ; passes
(clojure.test/is ())    ; passes
(clojure.test/is nil)   ; ** fails **
(clojure.test/is false) ; ** fails **

; We will perform explicit comparison against the boolean values instead of
; testing for truthyness.

; WHAT'S FALSE?
; The function 'false?' gives 'true' only on 'false'
; Anything else is 'NOT false' (but not necessarily 'true') 

(clojure.test/is (= false (false? '()     )))
(clojure.test/is (= false (false? []      )))
(clojure.test/is (= false (false? {}      )))
(clojure.test/is (= false (false? #{}     )))
(clojure.test/is (= false (false? nil     )))
(clojure.test/is (= true  (false? false   ))) ; only false is false
(clojure.test/is (= false (false? true    )))
(clojure.test/is (= false (false? 0       )))
(clojure.test/is (= false (false? 1       )))
(clojure.test/is (= false (false? "false" )))
(clojure.test/is (= false (false? "true"  )))
(clojure.test/is (= false (false? ""      )))
(clojure.test/is (= false (false? (fn []) ))) ; yeah that's far-fetched
(clojure.test/is (= false (false? (Boolean. false)))) ; an evil boxedJavaFalse is NOT false
(clojure.test/is (= false (false? (Boolean. true))))  ; an evil boxedJavaTrue  is NOT false

; WHAT'S TRUE?
; The function 'true?' gives 'true' only on 'true'
; Anything else is 'NOT true' (but not necessarily 'false') 

(clojure.test/is (= false (true? '()     )))
(clojure.test/is (= false (true? []      )))
(clojure.test/is (= false (true? {}      )))
(clojure.test/is (= false (true? #{}     )))
(clojure.test/is (= false (true? nil     )))
(clojure.test/is (= false (true? false   )))
(clojure.test/is (= true  (true? true    ))) ; only true is true
(clojure.test/is (= false (true? 0       )))
(clojure.test/is (= false (true? 1       )))
(clojure.test/is (= false (true? "false" )))
(clojure.test/is (= false (true? "true"  )))
(clojure.test/is (= false (true? ""      )))
(clojure.test/is (= false (true? (fn []) ))) ; yeah that's far-fetched
(clojure.test/is (= false (true? (Boolean. false)))) ; an evil boxedJavaFalse is also NOT true
(clojure.test/is (= false (true? (Boolean. true))))  ; an evil boxedJavaTrue  is also NOT true

; What's TRUTHY?
; Every 'thing' is 'truthy' except 'nil' and 'false'

(clojure.test/is (= true  (truthy? '()     )))
(clojure.test/is (= true  (truthy? []      )))
(clojure.test/is (= true  (truthy? {}      )))
(clojure.test/is (= true  (truthy? #{}     )))
(clojure.test/is (= false (truthy? nil     ))) ; only nil and false are not truthy (i.e. falsey)
(clojure.test/is (= false (truthy? false   ))) ; only nil and false are not truthy (i.e. falsey)
(clojure.test/is (= true  (truthy? true    )))
(clojure.test/is (= true  (truthy? 0       )))
(clojure.test/is (= true  (truthy? 1       )))
(clojure.test/is (= true  (truthy? "false" )))
(clojure.test/is (= true  (truthy? "true"  )))
(clojure.test/is (= true  (truthy? ""      )))
(clojure.test/is (= true  (truthy? (fn []) ))) ; yeah that's far-fetched
(clojure.test/is (= true  (truthy? (Boolean. false)))) ; an evil boxedJavaFalse is also truthy
(clojure.test/is (= true  (truthy? (Boolean. true))))  ; an evil boxedJavaTrue  is also truthy

; What's FALSEY?
; By construction, no 'thing' is 'falsey' except 'nil' and 'false'

(map (fn [x] 
         (clojure.test/is (= (falsey? x) (not (truthy? x))))
     )
     [ () [] {} #{} nil false true 0 1 "false" "true" "" (fn []) (Boolean. false) (Boolean. true) ]
)

; "not" of a 'thing' yields exactly "falsey?" of thing

(map (fn [x] 
         (clojure.test/is (= (falsey? x) (not x)))
     )
     [ () [] {} #{} nil false true 0 1 "false" "true" "" (fn []) (Boolean. false) (Boolean. true) ]
)

; "not∘not" of a thing yields exactly "truthy?" of a thing
; this corresponds to JavaScript's "!!" -- "bang bang, you are a boolean!"
; which, given an object, yields that object's truthy boolean value. 

(map (fn [x] 
         (clojure.test/is (= (truthy? x) (not (not x))))
     )
     [ () [] {} #{} nil false true 0 1 "false" "true" "" (fn []) (Boolean. false) (Boolean. true) ]
)