[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Surprising behavior of eq?
From: |
Zelphir Kaltstahl |
Subject: |
Re: Surprising behavior of eq? |
Date: |
Sun, 20 Sep 2020 17:42:26 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 |
Hello Stefan!
Thank you for your explanation as well!
On 9/20/20 3:57 PM, Stefan Schmiedl wrote:
> Let's have a little shop talk with guile:
>
> $ guile-3.0
> GNU Guile 3.0.4-dirty
> scheme@(guile-user)> (eqv? "a" "a")
> $1 = #t
>
> Hypothesis:
> guile's reader recognizes that the contents of both string literals
> are the same and feeds the same string to the calling function.
>
> Check:
> If that were the case, the two strings should not only be eqv? but
> also eq?
>
> scheme@(guile-user)> (eq? "a" "a")
> $2 = #t
>
> To see a different behaviour we need to avoid these literals and replace
> them by values not built while reading but while executing the code:
>
> scheme@(guile-user)> (equal? (list->string (list #\a)) (list->string (list
> #\a)))
> $3 = #t
>
> Now we compare two different string values which happen to end up with
> identical content. And, behold: They are neither eqv? nor eq?.
>
> scheme@(guile-user)> (eqv? (list->string (list #\a)) (list->string (list
> #\a)))
> $4 = #f
> scheme@(guile-user)> (eq? (list->string (list #\a)) (list->string (list #\a)))
> $5 = #f
>
>
> Now let's see if that is consistent with the standard:
>
> According to r5rs, section 6.1 "Equivalence predicates":
>
> The eqv? procedure returns #t if:
> ...
> * obj1 and obj2 are pairs, vectors, or strings that denote
> the same locations in the store (section 3.4).
>
> So we have learned
> * that guile's reader reuses "store locations" for
> strings of identical content
I even learned a little bit about store locations and that a "store"
exist as a concept in the implementation of Scheme and GNU Guile ; )
> * that eqv? is not the right predicate for content based string comparison
I see! Thanks!
> HTH
> s.
>
> "Zelphir Kaltstahl" <zelphirkaltstahl@posteo.de>, 20.09.2020, 15:09:
>
>> And I've noticed something more about equality stuff in the context of
>> tests:
>>
>> ~~~~
>> (eqv? "a" "a")
>> $3 = #t
>>
>> ;; but
>>
>> (define char->>string
>> (λ (c)
>> (list->string
>> (list c))))
>>
>> (import
>> ;; unit tests
>> (srfi srfi-64))
>> (test-begin "string-utils-test")
>>
>> (test-group
>> "char-to-string-test"
>>
>> (test-eqv "char->string converts a character to a string"
>> "a"
>> (char->string #\a)))
>>
>> (test-end "string-utils-test")
>>
>> %%%% Starting test string-utils-test (Writing full log to
>> "string-utils-test.log")
>> $2 = ("string-utils-test")
>> :19: FAIL char->>string converts a character to a string
>> # of unexpected failures 1
>> ~~~~
>>
>> So while (eqv? ...) gives the correct (?) result, the test procedure
>> (test-eqv ...) which seems to indicate using (eqv? ...) via its name
>> does not think of the two strings as equivalent.
>>
>>
>> On 20.09.20 14:19, Zelphir Kaltstahl wrote:
>>> Sorry, I misclicked "send" when I wanted to further edit my e-mail ...
>>>
>>> My Guile version is:
>>>
>>> ~~~~
>>> (version)
>>> $6 = "3.0.4"
>>> ~~~~
>>>
>>> On 20.09.20 14:16, Zelphir Kaltstahl wrote:
>>>> Hello Guile users,
>>>>
>>>> I just noticed something weird about eq?.
>>>>
>>>> My Guile version is:
>>>>
>>>>
>>>> I get the different results, depending on whether I define some
>>>> bindings in a let or using define:
>>>>
>>>> (In Emacs Geiser:)
>>>>
>>>> ~~~~
>>>> (define x '(10 9))
>>>> (define y '(10 9))
>>>> (eq? x y)
>>>> $2 = #f
>>>>
>>>> (let ([x '(10 9)]
>>>> [y '(10 9)])
>>>> (eq? x y))
>>>> $3 = #t
>>>> ~~~~
>>>>
>>>> Is this intentional or a bug?
>>>>
>>>> I first noticed something strange when writing the following code:
>>>>
>>>> ~~~~DEFINITION~~~~
>>>> (define make-multiple-list-remover
>>>> (λ (equal-proc)
>>>> (λ (lst unwanted)
>>>> (let loop ([remaining-list lst])
>>>> (cond
>>>> [(null? remaining-list)
>>>> '()]
>>>> [(equal-proc (car remaining-list) unwanted)
>>>> (loop (cdr remaining-list))]
>>>> [else
>>>> (cons (car remaining-list)
>>>> (loop (cdr remaining-list)))])))))
>>>> ~~~~
>>>>
>>>> ~~~~TEST~~~~
>>>> (let ([a '(9 10)]
>>>> [b '(9 10)])
>>>> (test-equal "make-multiple-list-remover-03"
>>>> `(1 2 (3) (4) ,a)
>>>> ((make-multiple-list-remover eq?)
>>>> `(a b (c) (d) ,a) b)))
>>>> ~~~~
>>>>
>>>> I was wondering, why the test fails. I think (eq? ...) should not be
>>>> able to see the equivalence of both lists a and b, just like when
>>>> defined using (define ...).
>>>>
>>>> I can also run it in the REPL and see the difference:
>>>>
>>>> ~~~~
>>>> (define a '(9 10))
>>>> (define b '(9 10))
>>>> ((make-multiple-list-remover eq?)
>>>> `(a b (c) (d) ,a) b)
>>>> $4 = (a b (c) (d) (9 10))
>>>>
>>>> (let ([a '(9 10)]
>>>> [b '(9 10)])
>>>> ((make-multiple-list-remover eq?)
>>>> `(a b (c) (d) ,a) b))
>>>> $5 = (a b (c) (d))
>>>> ~~~~
>>>>
>>>> Somehow the bindings of let seem to be different from the bindings
>>>> created using define. What about using define inside let?
>>>>
>>>> ~~~~
>>>>
>>>> ~~~~
>>>> --
>>>> repositories: https://notabug.org/ZelphirKaltstahl
>>> Somehow the bindings of let seem to be different from the bindings
>>> created using define. What about using define inside let?
>>>
>>> ~~~~
>>> (let ([unrelated 'bla])
>>> (define a '(9 10))
>>> (define b '(9 10))
>>> ((make-multiple-list-remover eq?)
>>> `(a b (c) (d) ,a) b))
>>> $7 = (a b (c) (d))
>>> ~~~~
>>>
>>> So there the define usage also differs from when I use define on the top
>>> level. Perhaps that is the difference? On which level the bindings are
>>> defined?
>>>
>>> Regards,
>>> Zelphir
>>>
>
> --
> Stefan Schmiedl
> EDV-Beratung Schmiedl, Berghangstr. 5, 93413 Cham
> Büro: +49 (0) 9971 9966 989, Mobil: +49 (0) 160 9981 6278
Best regards,
Zelphir
- Re: Surprising behavior of eq?, (continued)
- Re: Surprising behavior of eq?, Zelphir Kaltstahl, 2020/09/20
- Re: Surprising behavior of eq?, Christopher Lemmer Webber, 2020/09/20
- Re: Surprising behavior of eq?, Zelphir Kaltstahl, 2020/09/20
- Re: Surprising behavior of eq?, John Cowan, 2020/09/20
- Re: Surprising behavior of eq?, Zelphir Kaltstahl, 2020/09/20
- Re: Surprising behavior of eq?, tomas, 2020/09/20
- Re: Surprising behavior of eq?, John Cowan, 2020/09/20
- Re: Surprising behavior of eq?, Linus Björnstam, 2020/09/20
- Re: Surprising behavior of eq?, John Cowan, 2020/09/20
- Re: Surprising behavior of eq?, Stefan Schmiedl, 2020/09/20
- Re: Surprising behavior of eq?,
Zelphir Kaltstahl <=
Re: Surprising behavior of eq?, Taylan Kammer, 2020/09/20