Тұлғалар дәлелден өзгеше нәрсе қайтарады деп күтілуде ме?

Міне, мысалы, identity < «docstring» өз дәлелін қайтарады дегенді білдіреді. мүлдем дұрыс емес:

(let [x Double/NaN] (identical? x x)) ;=> false
(let [x (identity Double/NaN)] (identical? x x)) ;=> true

Бұл күтілуде ме? Немесе identity функциясымен қандай да бір қате бар ма?

5
Бұл, бәлкім, боксқа байланысты - Double/NaN бірінші мысалда екі рет қорапталған, бірақ секундына тек бір рет қапталған қос
қосылды автор Lee, көзі

6 жауаптар

You appear to have found an edge case involving identity, identical?, and primitive vs object equality. Note that in Java, java.lang.Double/NaN is a primitive:

public static final double NaN

Бірақ Java Objects бірдей салыстырады:

; clojure.core
(defn identical?
  "Tests if 2 arguments are the same object"
  {:inline (fn [x y] `(. clojure.lang.Util identical ~x ~y))
   :inline-arities #{2}
   :added "1.0"}
  ([x y] (clojure.lang.Util/identical x y)))

// clojure/lang/Util.java
static public boolean identical(Object k1, Object k2){
    return k1 == k2;
}

NaN-ді қораптағы қарабайыр емес орнына Екі нысанға мәжбүрлеу үшін осы трюкті қолданып көріңіз:

tupelo.core=> (let [x (Double. Double/NaN)] 
  (spyxx x) 
  (identical? x x))

x => java.lang.Double->NaN
true

Мен әртүрлі пайдалану жағдайларында пайда болатын/мүмкін емес қарабайыр NaN-дің автобоксингі сіз көріп отырған айырмашылықтардың себебі болып табылады.

8
қосылды
Ақыр аяғында бұл мәселе дәл сол сұрақты қойып отыр: сіз сұрақ қойғаныңыз секілді, сіз Double даладағы NaN қорапшасын. Бұл басқа нәрсе емес. Бұл жауаптың жоқтығы - бұл identity және identical? екеуінің де autoboxing дегенді білдіретін түсіндірмесі.
қосылды автор amalloy, көзі

You appear to have found an edge case involving identity, identical?, and primitive vs object equality. Note that in Java, java.lang.Double/NaN is a primitive:

public static final double NaN

Бірақ Java Objects бірдей салыстырады:

; clojure.core
(defn identical?
  "Tests if 2 arguments are the same object"
  {:inline (fn [x y] `(. clojure.lang.Util identical ~x ~y))
   :inline-arities #{2}
   :added "1.0"}
  ([x y] (clojure.lang.Util/identical x y)))

// clojure/lang/Util.java
static public boolean identical(Object k1, Object k2){
    return k1 == k2;
}

NaN-ді қораптағы қарабайыр емес орнына Екі нысанға мәжбүрлеу үшін осы трюкті қолданып көріңіз:

tupelo.core=> (let [x (Double. Double/NaN)] 
  (spyxx x) 
  (identical? x x))

x => java.lang.Double->NaN
true

Мен әртүрлі пайдалану жағдайларында пайда болатын/мүмкін емес қарабайыр NaN-дің автобоксингі сіз көріп отырған айырмашылықтардың себебі болып табылады.

8
қосылды
Ақыр аяғында бұл мәселе дәл сол сұрақты қойып отыр: сіз сұрақ қойғаныңыз секілді, сіз Double даладағы NaN қорапшасын. Бұл басқа нәрсе емес. Бұл жауаптың жоқтығы - бұл identity және identical? екеуінің де autoboxing дегенді білдіретін түсіндірмесі.
қосылды автор amalloy, көзі

Аланның бокстағы жауабына кішкене түс қосу үшін:

Сіз осылай енгізілген == функциясын қарастыруыңыз мүмкін:

public boolean equiv(Number x, Number y){
    return x.doubleValue() == y.doubleValue();
}

Бұл екі нақты double s салыстыруын жасайды. Сіздің мысалыңыз == :

(let [x (identity Double/NaN)] (== x x))
=> false
(let [x (identity Double/POSITIVE_INFINITY)] (== x x))
=> true

Не болып жатыр? Неге NaN == NaN жалған? Ал, == пайдаланып қарабайыр салыстыру шынымен NaN үшін жалғандықты қайтаруы керек. IEEE 754 және Java сияқты әдістерде бұл тәсіл ерекше көрінеді. Бұл өздігімен салыстырғанда өзіне тең келмейтін жалғыз «нөмір».

Бір жағынан, объективті теңдестіру Java-те қандай-да бір нәрсе болуы мүмкін екендігін көруге болады:

(identical? 127 127)
=> true
(identical? 128 128)
=> false

Себебі java бірінші 2 ^ 8 белгісінің емес кэшін кэширеді, сондықтан 127 с салыстыру үшін бірінші мысалда бірдей нысан бар, бірақ екінші мысалда 128 s түрлі нысандар болып табылады. Мәселен, теңдікті тексеру арқылы хабардар болу үшін кейбір алғыстар бар!

Бірақ мұнда басты провайдер: identity жұмыс істейді! Тек «нәрсені» салыстыра отырып, «теңдік» ұғымы соншалықты қарапайым емес сияқты, салыстыру кезінде абай болыңыз!

3
қосылды
Бұл қайтарылған мәндер бір-бірінен ерекшеленетіні туралы емес, нақты қай қайтарылған мәндер туралы емес, мәселеге қатысты жауап бермейді.
қосылды автор Sam Estep, көзі

Аланның бокстағы жауабына кішкене түс қосу үшін:

Сіз осылай енгізілген == функциясын қарастыруыңыз мүмкін:

public boolean equiv(Number x, Number y){
    return x.doubleValue() == y.doubleValue();
}

Бұл екі нақты double s салыстыруын жасайды. Сіздің мысалыңыз == :

(let [x (identity Double/NaN)] (== x x))
=> false
(let [x (identity Double/POSITIVE_INFINITY)] (== x x))
=> true

Не болып жатыр? Неге NaN == NaN жалған? Ал, == пайдаланып қарабайыр салыстыру шынымен NaN үшін жалғандықты қайтаруы керек. IEEE 754 және Java сияқты әдістерде бұл тәсіл ерекше көрінеді. Бұл өздігімен салыстырғанда өзіне тең келмейтін жалғыз «нөмір».

Бір жағынан, объективті теңдестіру Java-те қандай-да бір нәрсе болуы мүмкін екендігін көруге болады:

(identical? 127 127)
=> true
(identical? 128 128)
=> false

Себебі java бірінші 2 ^ 8 белгісінің емес кэшін кэширеді, сондықтан 127 с салыстыру үшін бірінші мысалда бірдей нысан бар, бірақ екінші мысалда 128 s түрлі нысандар болып табылады. Мәселен, теңдікті тексеру арқылы хабардар болу үшін кейбір алғыстар бар!

Бірақ мұнда басты провайдер: identity жұмыс істейді! Тек «нәрсені» салыстыра отырып, «теңдік» ұғымы соншалықты қарапайым емес сияқты, салыстыру кезінде абай болыңыз!

3
қосылды
Бұл қайтарылған мәндер бір-бірінен ерекшеленетіні туралы емес, нақты қай қайтарылған мәндер туралы емес, мәселеге қатысты жауап бермейді.
қосылды автор Sam Estep, көзі

identity «өзінің дәлелін қайтарады ?

Бұл аргументі дегеннің мәніне байланысты.

  • Егер функциясының қоңырау формасындағы бағаланған өрнегі болса, әрдайым емес .
  • Егер

Аномалия Clojure функциясын шақыратындықтан туындайды.

Осының бәрі - бұл әрбір Clojure функциясының шақыруының әрбір аргументін Object түріне аудару - сәйкес Java класына оралған примитивтерден басқа сәйкестік әрекеті: long </кодты> Long ішіне және т.б.

Сондықтан identity функциясы, негізінен (defn identity [x] x) ), қарабайыр дәлелді қайтармайды. Ол мүмкін емес, өйткені оны ешқашан көрмейді.


Мысалы, өрнек қарастырайық

(inc 3)

3 деген сөз - сөзсіз long . (inc 3) қандай типті? Келіңіздер, Clojure:

(type (inc 3))
=> java.lang.Long

... қапталған Ұзын нысаны.

3 - қарабайыр long екеніне сенімдіміз бе?

(type 3)
=> java.lang.Long

Aaaaaaagh! Бұл да қорапты!

Not necessarily! You can't tell, because by the time the body of type sees 3, it is boxed, whether or not it was so to the reader/compiler. The Clojure documentation is silent on the point. It just says that numeric literals are generally represented as per Java.

Сонымен, жалпы - бұл қарабайыр аргументтерді боксқа жауапты identity сияқты нақты функция емес, бағалау механизмі. Бұл авто-бокс.

Сіздің мысалыңызда, примитивтер, кем дегенде, let нысандарында сақталмаған,

(let [x 1.0] (identical? x x)) ;=> false
(let [x (identity 1.0)] (identical? x x)) ;=> true

identical? 1.0 екеуінің арасындағы айырмашылықты анықтай алуы, ол <�қарашық double түрінде сақталғанын көрсетеді. (Мінез-құлықтың Double/NaN мәнімен ешқандай қатысы жоқ екендігін көрсету үшін жай қос қолданамын).

Енді санды барда қоюға тырысайық:

(def x 1.0)

(identical? x x) ;=> true
(let [x (identity x)] (identical? x x)) ;=> true

Бұл қорапты.

Біз осында болсақ, автобустың идемпотент болып табылады:

(identical? x (identity x)) ;=> true

Жоғарыда айтылғандарға қарағанда, Алан Томпсонның және

0
қосылды

identity «өзінің дәлелін қайтарады ?

Бұл аргументі дегеннің мәніне байланысты.

  • Егер функциясының қоңырау формасындағы бағаланған өрнегі болса, әрдайым емес .
  • Егер

Аномалия Clojure функциясын шақыратындықтан туындайды.

Осының бәрі - бұл әрбір Clojure функциясының шақыруының әрбір аргументін Object түріне аудару - сәйкес Java класына оралған примитивтерден басқа сәйкестік әрекеті: long </кодты> Long ішіне және т.б.

Сондықтан identity функциясы, негізінен (defn identity [x] x) ), қарабайыр дәлелді қайтармайды. Ол мүмкін емес, өйткені оны ешқашан көрмейді.


Мысалы, өрнек қарастырайық

(inc 3)

3 деген сөз - сөзсіз long . (inc 3) қандай типті? Келіңіздер, Clojure:

(type (inc 3))
=> java.lang.Long

... қапталған Ұзын нысаны.

3 - қарабайыр long екеніне сенімдіміз бе?

(type 3)
=> java.lang.Long

Aaaaaaagh! Бұл да қорапты!

Not necessarily! You can't tell, because by the time the body of type sees 3, it is boxed, whether or not it was so to the reader/compiler. The Clojure documentation is silent on the point. It just says that numeric literals are generally represented as per Java.

Сонымен, жалпы - бұл қарабайыр аргументтерді боксқа жауапты identity сияқты нақты функция емес, бағалау механизмі. Бұл авто-бокс.

Сіздің мысалыңызда, примитивтер, кем дегенде, let нысандарында сақталмаған,

(let [x 1.0] (identical? x x)) ;=> false
(let [x (identity 1.0)] (identical? x x)) ;=> true

identical? 1.0 екеуінің арасындағы айырмашылықты анықтай алуы, ол <�қарашық double түрінде сақталғанын көрсетеді. (Мінез-құлықтың Double/NaN мәнімен ешқандай қатысы жоқ екендігін көрсету үшін жай қос қолданамын).

Енді санды барда қоюға тырысайық:

(def x 1.0)

(identical? x x) ;=> true
(let [x (identity x)] (identical? x x)) ;=> true

Бұл қорапты.

Біз осында болсақ, автобустың идемпотент болып табылады:

(identical? x (identity x)) ;=> true

Жоғарыда айтылғандарға қарағанда, Алан Томпсонның және

0
қосылды