Hisobga olish shaxsning argumentidan boshqacha fikr bildirishi kutiladimi?

Mana shuning uchun identity chaqirgan qaytarilgan qiymatni o'zgartiruvchi misol keltirilgan. docstring "o'z argumentini qaytaradi" deb aytishim kerak. butunlay to'g'ri emas:

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

Bu kutilganmi? Yoki qanday qilib identifikatori funktsiyasi bilan xatolik yuz berdi?

5
Bu ehtimol boks bo'yicha - Double/NaN dastlabki juftlik kodini qaytaradi, bu birinchi misolda ikki marta kutilgan, lekin faqat bir marta.
qo'shib qo'ydi muallif Lee, manba

6 javoblar

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

Ammo bir xil Java ob'ektlarini solishtiradi:

; 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 ni qutisiga arzimas ibtidoiy o'rniga ikki ob'ektga majbur qilish uchun ushbu usulni sinab ko'ring:

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

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

Men turli xil foydalanish holatlarida yuzaga kelishi mumkin bo'lgan, sodda NaNning avtoboksini kesish siz ko'rayotgan farqlarning sababi ekanligiga shubha qilaman.

8
qo'shib qo'ydi
Oxir-oqibat bu savol shunchaki bir xil narsa: bu sizning identifikatoringiz bo'lgani kabi, siz ham ikki juftlikdagi "NaN" qutisiga aylanasiz. Bu haqiqatan ham boshqa narsa emas. Menimcha, bu javob yo'qolgan yagona narsa identifikatori va identical? nima uchun autoboxingni talab qiladi.
qo'shib qo'ydi muallif amalloy, manba

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

Ammo bir xil Java ob'ektlarini solishtiradi:

; 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 ni qutisiga arzimas ibtidoiy o'rniga ikki ob'ektga majbur qilish uchun ushbu usulni sinab ko'ring:

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

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

Men turli xil foydalanish holatlarida yuzaga kelishi mumkin bo'lgan, sodda NaNning avtoboksini kesish siz ko'rayotgan farqlarning sababi ekanligiga shubha qilaman.

8
qo'shib qo'ydi
Oxir-oqibat bu savol shunchaki bir xil narsa: bu sizning identifikatoringiz bo'lgani kabi, siz ham ikki juftlikdagi "NaN" qutisiga aylanasiz. Bu haqiqatan ham boshqa narsa emas. Menimcha, bu javob yo'qolgan yagona narsa identifikatori va identical? nima uchun autoboxingni talab qiladi.
qo'shib qo'ydi muallif amalloy, manba

Alanning boks bo'yicha bergan javobiga bir oz rang qo'shish uchun:

Quyidagi tarzda amalga oshirilgan == funksiyasiga murojaat qilishingiz mumkin:

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

Bu ikki haqiqiy double ning ibtidoiy taqqoslashini amalga oshiradi. Sizning namunangiz: == :

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

Nima gaplar? Nima uchun NaN == NaN noto'g'ri? Xullas, == yordamida ibtidoiy taqqoslash aslida NaN uchun noto'g'ri bo'lishi kerak. Ushbu usulni IEEE 754 va Java kabi usulda ko'rsatib qo'yish juda g'alati. Bu o'zi bilan solishtirganda o'zini o'zi tenglamaydigan yagona "raqam".

Bir tomondan Java ob'ektidagi tenglik ob'ekti qanday g'alati bo'lganini ko'rish uchun quyidagilarni o'qing:

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

Buning sababi java birinchi 2 ^ 8 imzosiz intsni keshlashadi, shuning uchun taqqoslanadigan 127 s birinchi misolda bir xil ob'ekt, lekin ikkinchi misolda 128 s har xil narsalar. Xullas, tenglik tekshiruvi bilan taniqli bo'lish uchun ba'zi narsalar bor!

Lekin bu erda asosiy paket: identity kerak bo'lsa ishlaydi! Faqat "tenglik" tushunchasi shu qadar oddiy emas, chunki narsalarni solishtirishda ehtiyot bo'ling!

3
qo'shib qo'ydi
Bu qaytib kelgan qiymatlar bir-biridan farqli bo'lganligi haqida emas, balki qaytib kelgan qadriyatlar xususida emas, balki savolga javob bermaydi.
qo'shib qo'ydi muallif Sam Estep, manba

Alanning boks bo'yicha bergan javobiga bir oz rang qo'shish uchun:

Quyidagi tarzda amalga oshirilgan == funksiyasiga murojaat qilishingiz mumkin:

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

Bu ikki haqiqiy double ning ibtidoiy taqqoslashini amalga oshiradi. Sizning namunangiz: == :

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

Nima gaplar? Nima uchun NaN == NaN noto'g'ri? Xullas, == yordamida ibtidoiy taqqoslash aslida NaN uchun noto'g'ri bo'lishi kerak. Ushbu usulni IEEE 754 va Java kabi usulda ko'rsatib qo'yish juda g'alati. Bu o'zi bilan solishtirganda o'zini o'zi tenglamaydigan yagona "raqam".

Bir tomondan Java ob'ektidagi tenglik ob'ekti qanday g'alati bo'lganini ko'rish uchun quyidagilarni o'qing:

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

Buning sababi java birinchi 2 ^ 8 imzosiz intsni keshlashadi, shuning uchun taqqoslanadigan 127 s birinchi misolda bir xil ob'ekt, lekin ikkinchi misolda 128 s har xil narsalar. Xullas, tenglik tekshiruvi bilan taniqli bo'lish uchun ba'zi narsalar bor!

Lekin bu erda asosiy paket: identity kerak bo'lsa ishlaydi! Faqat "tenglik" tushunchasi shu qadar oddiy emas, chunki narsalarni solishtirishda ehtiyot bo'ling!

3
qo'shib qo'ydi
Bu qaytib kelgan qiymatlar bir-biridan farqli bo'lganligi haqida emas, balki qaytib kelgan qadriyatlar xususida emas, balki savolga javob bermaydi.
qo'shib qo'ydi muallif Sam Estep, manba

identity "o'z argumentini qaytaradi" bormi?

Bu sizning argumenti degan ma'noni anglatadi.

  • Agar funktsiyani qidirish formatida baholangan ifoda bo'lsa, har doim emas, .
  • Agar funksiyasi tanasi kiritishda suyakka ko'rgan bo'lsa, unda ha yo'q. </</ul>

    Anomaliya Clojurening vazifalarni chaqirishi sababli paydo bo'ladi.

    • Clojure funktsiyalari mos keladigan ob'ektlardir IFn interfeys .
    • A Clojure funktsiya chaqiruvi call dan biriga aylanadi usullari - arity uchun haddan tashqari yuklangan - funktsiya obyekti.
    • Barcha chaqiradigan usullari Object parametrlariga ega.

    Bularning barchasi shundan iboratki, har bir Clojure funktsiyasi chaqiruvi har qanday dalilni Object - identifikatsiya qilish amaliyoti - xuddi Java-classga o'ralgan primitivlar bundan mustasno: long kodi> Long ga yozing va hokazo.

    Demak, identifikatori funktsiyasi, asosan (dafn identifikatori [x] x) ), ibtidoiy dalilni qaytarmaydi. Hech narsa ko'rmaydi, chunki buni hech qachon ko'rmaydi.


    Masalan, ifodani ko'rib chiqaylik

    (inc 3)
    

    3 raqami, albatta, long . (inc 3) qanday turdagi? Keling, Clojurega:

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

    ... kutilgan Long ob'ektidan foydalaning.

    3 ibtidoiy uzun ekanligiga ishonchimiz komilmi ?:

    (type 3)
    => java.lang.Long
    

    Aaaaaaagh! U ham kutulandi!

    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.

    Shunday qilib, umuman - bu ibtidoiy dalillarni boks uchun javobgar bo'lgan identity kabi maxsus funktsiyani emas, balki baholash mexanizmi. Bu avtomatik boksdir.

    Sizning namunangiz ko'rsatadiki, ibtidoiylar hech bo'lmaganda let shakllarida saqlanmagan holda saqlanadi:

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

    identical? 1.0 ikki qutisi o'rtasidagi farqni aniqlay olishi ibtidoiy double sifatida saqlanganligini ko'rsatadi. (Xatti-harakatlarning Double/NaN maxsus qiymati bilan hech qanday aloqasi yo'qligini ko'rsatish uchun oddiy double dan foydalanganman).

    Keling, bu raqamni borga qo'yib ko'ring:

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

    Bu kutilgan.

    Biz bu yerda ekanmiz, avtomatik boks idempotent:

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

    Yuqorida keltirilgan ma'lumotlarga ko'ra, Alan Thompson va Joshning javoblari va Alan Malloy va Lee ning izohlari keltirilgan. Men faqat o'zlarini bog'lab, baliqni o'ynatganini his qildim.

0
qo'shib qo'ydi

identity "o'z argumentini qaytaradi" bormi?

Bu sizning argumenti degan ma'noni anglatadi.

  • Agar funktsiyani qidirish formatida baholangan ifoda bo'lsa, har doim emas, .
  • Agar funksiyasi tanasi kiritishda suyakka ko'rgan bo'lsa, unda ha yo'q. </</ul>

    Anomaliya Clojurening vazifalarni chaqirishi sababli paydo bo'ladi.

    • Clojure funktsiyalari mos keladigan ob'ektlardir IFn interfeys .
    • A Clojure funktsiya chaqiruvi call dan biriga aylanadi usullari - arity uchun haddan tashqari yuklangan - funktsiya obyekti.
    • Barcha chaqiradigan usullari Object parametrlariga ega.

    Bularning barchasi shundan iboratki, har bir Clojure funktsiyasi chaqiruvi har qanday dalilni Object - identifikatsiya qilish amaliyoti - xuddi Java-classga o'ralgan primitivlar bundan mustasno: long kodi> Long ga yozing va hokazo.

    Demak, identifikatori funktsiyasi, asosan (dafn identifikatori [x] x) ), ibtidoiy dalilni qaytarmaydi. Hech narsa ko'rmaydi, chunki buni hech qachon ko'rmaydi.


    Masalan, ifodani ko'rib chiqaylik

    (inc 3)
    

    3 raqami, albatta, long . (inc 3) qanday turdagi? Keling, Clojurega:

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

    ... kutilgan Long ob'ektidan foydalaning.

    3 ibtidoiy uzun ekanligiga ishonchimiz komilmi ?:

    (type 3)
    => java.lang.Long
    

    Aaaaaaagh! U ham kutulandi!

    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.

    Shunday qilib, umuman - bu ibtidoiy dalillarni boks uchun javobgar bo'lgan identity kabi maxsus funktsiyani emas, balki baholash mexanizmi. Bu avtomatik boksdir.

    Sizning namunangiz ko'rsatadiki, ibtidoiylar hech bo'lmaganda let shakllarida saqlanmagan holda saqlanadi:

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

    identical? 1.0 ikki qutisi o'rtasidagi farqni aniqlay olishi ibtidoiy double sifatida saqlanganligini ko'rsatadi. (Xatti-harakatlarning Double/NaN maxsus qiymati bilan hech qanday aloqasi yo'qligini ko'rsatish uchun oddiy double dan foydalanganman).

    Keling, bu raqamni borga qo'yib ko'ring:

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

    Bu kutilgan.

    Biz bu yerda ekanmiz, avtomatik boks idempotent:

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

    Yuqorida keltirilgan ma'lumotlarga ko'ra, Alan Thompson va Joshning javoblari va Alan Malloy va Lee ning izohlari keltirilgan. Men faqat o'zlarini bog'lab, baliqni o'ynatganini his qildim.

0
qo'shib qo'ydi