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" <zelphirkaltst...@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