GNU bug report logs - #21855
eq?

Previous Next

Package: guile;

Reported by: Atticus <atticus0 <at> posteo.org>

Date: Sat, 7 Nov 2015 17:06:02 UTC

Severity: normal

Done: Andy Wingo <wingo <at> pobox.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 21855 in the body.
You can then email your comments to 21855 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#21855; Package guile. (Sat, 07 Nov 2015 17:06:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Atticus <atticus0 <at> posteo.org>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Sat, 07 Nov 2015 17:06:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Atticus <atticus0 <at> posteo.org>
To: bug-guile <at> gnu.org
Subject: eq?
Date: Sat, 07 Nov 2015 13:58:48 +0100
So I wanted to try out gnu guix and thus make myself more familiar with
guile first. While running some tests I encountered a problem/bug with eq?:

$ guile -v
guile (GNU Guile) 2.1.1

$ guile
scheme@(guile-user)>
(define (multirember a lat)
  (cond
   ((null? lat) '())
   ((eq? (car lat) a) (multirember a (cdr lat)))
   (else (cons (car lat) (multirember a (cdr lat))))))
   
scheme@(guile-user)> (multirember '(a b) '(x y (a b) z (a b)))
$1 = (x y z)

So why does guile return (x y z)? I expected (x y (a b) z (a b)). I know
eq? should only be used with symbols (and thus this example is more
theoretical) but nevertheless the return value is not right, since (eq?
'(a b) '(a b)) returns #f (Btw same in guile 2.0.11).




Information forwarded to bug-guile <at> gnu.org:
bug#21855; Package guile. (Sun, 08 Nov 2015 10:59:01 GMT) Full text and rfc822 format available.

Message #8 received at 21855 <at> debbugs.gnu.org (full text, mbox):

From: <tomas <at> tuxteam.de>
To: Atticus <atticus0 <at> posteo.org>
Cc: 21855 <at> debbugs.gnu.org
Subject: Re: bug#21855: eq?
Date: Sun, 8 Nov 2015 11:23:23 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sat, Nov 07, 2015 at 01:58:48PM +0100, Atticus wrote:
> So I wanted to try out gnu guix and thus make myself more familiar with
> guile first. While running some tests I encountered a problem/bug with eq?:
> 
> $ guile -v
> guile (GNU Guile) 2.1.1
> 
> $ guile
> scheme@(guile-user)>
> (define (multirember a lat)
>   (cond
>    ((null? lat) '())
>    ((eq? (car lat) a) (multirember a (cdr lat)))
>    (else (cons (car lat) (multirember a (cdr lat))))))
>    
> scheme@(guile-user)> (multirember '(a b) '(x y (a b) z (a b)))
> $1 = (x y z)
> 
> So why does guile return (x y z)? I expected (x y (a b) z (a b)). I know
> eq? should only be used with symbols (and thus this example is more
> theoretical) but nevertheless the return value is not right, since (eq?
> '(a b) '(a b)) returns #f (Btw same in guile 2.0.11).

Hm. As far as I know (eq? '(a b) '(a b)) is not *guaranteed* to evaluate
to #f. The implementation might be free to re-use things it "knows" to be
constant (I might be wrong, though).

Regards
- -- t
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iEYEARECAAYFAlY/IpsACgkQBcgs9XrR2kZMoACZAc49Kzq9JzteJovmzRpH2WLv
M3YAnibf8NUd5bspCqCP2cQiAWNSiREt
=O1dE
-----END PGP SIGNATURE-----




Information forwarded to bug-guile <at> gnu.org:
bug#21855; Package guile. (Sun, 08 Nov 2015 13:32:01 GMT) Full text and rfc822 format available.

Message #11 received at 21855 <at> debbugs.gnu.org (full text, mbox):

From: Atticus <atticus0 <at> posteo.org>
To: tomas <at> tuxteam.de
Cc: 21855 <at> debbugs.gnu.org
Subject: Re: bug#21855: eq?
Date: Sun, 08 Nov 2015 14:30:42 +0100
tomas <at> tuxteam.de writes:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Sat, Nov 07, 2015 at 01:58:48PM +0100, Atticus wrote:
>> So I wanted to try out gnu guix and thus make myself more familiar with
>> guile first. While running some tests I encountered a problem/bug with eq?:
>> 
>> $ guile -v
>> guile (GNU Guile) 2.1.1
>> 
>> $ guile
>> scheme@(guile-user)>
>> (define (multirember a lat)
>>   (cond
>>    ((null? lat) '())
>>    ((eq? (car lat) a) (multirember a (cdr lat)))
>>    (else (cons (car lat) (multirember a (cdr lat))))))
>>    
>> scheme@(guile-user)> (multirember '(a b) '(x y (a b) z (a b)))
>> $1 = (x y z)
>> 
>> So why does guile return (x y z)? I expected (x y (a b) z (a b)). I know
>> eq? should only be used with symbols (and thus this example is more
>> theoretical) but nevertheless the return value is not right, since (eq?
>> '(a b) '(a b)) returns #f (Btw same in guile 2.0.11).
>
> Hm. As far as I know (eq? '(a b) '(a b)) is not *guaranteed* to evaluate
> to #f. The implementation might be free to re-use things it "knows" to be
> constant (I might be wrong, though).

Yes you are right that the implementation may treat it as non #f if both
arguments refer to the same object. In r5rs (and also r6rs) (eq? '(a)
'(a)) is unspecified (r5rs, page 19) and thus implementation dependant
but I don't think the behaviour of eq? is consistent in guile. As I said
(eq? '(a b) '(a b)) on its own returns #f and imho there is no reason why eq?
inside a procedure (in this example in 'multirember') should behave
different, since the '(a b) in the second argument does not refer to the
'(a b) of the first argument.

Since it's not clear if this is a "real" bug, perhaps a further
discussion at guile-user <at> gnu.org would be better. What is the
recommended proceeding in such a case? A reply with the pseudo-header
"X-Debbugs-CC: guile-user <at> gnu.org"? Or is that not necessary and a
simple mail to guile-user to discuss this topic is sufficient?

Btw sorry for the bad bug report, I shoud have read the documentation
(didn't include the necessary pseudo-headers)




Information forwarded to bug-guile <at> gnu.org:
bug#21855; Package guile. (Sun, 08 Nov 2015 14:14:02 GMT) Full text and rfc822 format available.

Message #14 received at 21855 <at> debbugs.gnu.org (full text, mbox):

From: tomas <at> tuxteam.de
To: Atticus <atticus0 <at> posteo.org>
Cc: 21855 <at> debbugs.gnu.org
Subject: Re: bug#21855: eq?
Date: Sun, 8 Nov 2015 14:38:35 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sun, Nov 08, 2015 at 02:30:42PM +0100, Atticus wrote:

[...]

> Yes you are right that the implementation may treat it as non #f if both
> arguments refer to the same object. In r5rs (and also r6rs) (eq? '(a)
> '(a)) is unspecified (r5rs, page 19) and thus implementation dependant
> but I don't think the behaviour of eq? is consistent in guile.

My hunch is that it *can't* be consistent (see below)

>                                                                As I said
> (eq? '(a b) '(a b)) on its own returns #f and imho there is no reason why eq?
> inside a procedure (in this example in 'multirember') should behave
> different, since the '(a b) in the second argument does not refer to the
> '(a b) of the first argument.

Modulo vagaries of the optimizer :-)

> Since it's not clear if this is a "real" bug, perhaps a further
> discussion at guile-user <at> gnu.org would be better. What is the
> recommended proceeding in such a case? A reply with the pseudo-header
> "X-Debbugs-CC: guile-user <at> gnu.org"? Or is that not necessary and a
> simple mail to guile-user to discuss this topic is sufficient?

Note that I'm not authoritative in this questions, so you'll have to
wait on someone with more knowledge than me for a more definiteve answer.

But as far as I can gather, those things can get caught in a common
subexpression elimination[1] step, and the results will depend on the
current optimization strategies. That's why r5rs is vague about that.
They (rightfully) don't want to shut off those (in some cases vital)
optimizations.

The take away (for me, at least) is "use eq? just for symbols", at
least unless you know what you are doing.

[1] <https://wingolog.org/archives/2014/08/25/revisiting-common-subexpression-elimination-in-guile>

regards
- -- t
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iEYEARECAAYFAlY/UFsACgkQBcgs9XrR2kaLQwCeKByrAN8ODfbCkIqRt8RMEpNL
9fcAmwTvngBuJ4qSlybyu/miPX8LROiS
=or0E
-----END PGP SIGNATURE-----




Information forwarded to bug-guile <at> gnu.org:
bug#21855; Package guile. (Mon, 09 Nov 2015 07:59:01 GMT) Full text and rfc822 format available.

Message #17 received at 21855 <at> debbugs.gnu.org (full text, mbox):

From: Atticus <atticus0 <at> posteo.org>
To: tomas <at> tuxteam.de
Cc: 21855 <at> debbugs.gnu.org
Subject: Re: bug#21855: eq?
Date: Mon, 09 Nov 2015 08:57:59 +0100
tomas <at> tuxteam.de writes:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Sun, Nov 08, 2015 at 02:30:42PM +0100, Atticus wrote:
>
> [...]
>
>> Yes you are right that the implementation may treat it as non #f if both
>> arguments refer to the same object. In r5rs (and also r6rs) (eq? '(a)
>> '(a)) is unspecified (r5rs, page 19) and thus implementation dependant
>> but I don't think the behaviour of eq? is consistent in guile.
>
> My hunch is that it *can't* be consistent (see below)
>
>>                                                                As I said
>> (eq? '(a b) '(a b)) on its own returns #f and imho there is no reason why eq?
>> inside a procedure (in this example in 'multirember') should behave
>> different, since the '(a b) in the second argument does not refer to the
>> '(a b) of the first argument.
>
> Modulo vagaries of the optimizer :-)

:-)

>> Since it's not clear if this is a "real" bug, perhaps a further
>> discussion at guile-user <at> gnu.org would be better. What is the
>> recommended proceeding in such a case? A reply with the pseudo-header
>> "X-Debbugs-CC: guile-user <at> gnu.org"? Or is that not necessary and a
>> simple mail to guile-user to discuss this topic is sufficient?
>
> Note that I'm not authoritative in this questions, so you'll have to
> wait on someone with more knowledge than me for a more definiteve answer.

Ok.

> But as far as I can gather, those things can get caught in a common
> subexpression elimination[1] step, and the results will depend on the
> current optimization strategies. That's why r5rs is vague about that.
> They (rightfully) don't want to shut off those (in some cases vital)
> optimizations.
>
> The take away (for me, at least) is "use eq? just for symbols", at
> least unless you know what you are doing.
>
> [1] <https://wingolog.org/archives/2014/08/25/revisiting-common-subexpression-elimination-in-guile>

Thanks for the link; an interesting read.




Reply sent to Andy Wingo <wingo <at> pobox.com>:
You have taken responsibility. (Fri, 24 Jun 2016 15:32:02 GMT) Full text and rfc822 format available.

Notification sent to Atticus <atticus0 <at> posteo.org>:
bug acknowledged by developer. (Fri, 24 Jun 2016 15:32:02 GMT) Full text and rfc822 format available.

Message #22 received at 21855-done <at> debbugs.gnu.org (full text, mbox):

From: Andy Wingo <wingo <at> pobox.com>
To: <tomas <at> tuxteam.de>
Cc: Atticus <atticus0 <at> posteo.org>, 21855-done <at> debbugs.gnu.org
Subject: Re: bug#21855: eq?
Date: Fri, 24 Jun 2016 17:31:11 +0200
On Sun 08 Nov 2015 11:23, <tomas <at> tuxteam.de> writes:

> On Sat, Nov 07, 2015 at 01:58:48PM +0100, Atticus wrote:
>> So I wanted to try out gnu guix and thus make myself more familiar with
>> guile first. While running some tests I encountered a problem/bug with eq?:
>> 
>> $ guile -v
>> guile (GNU Guile) 2.1.1
>> 
>> $ guile
>> scheme@(guile-user)>
>> (define (multirember a lat)
>>   (cond
>>    ((null? lat) '())
>>    ((eq? (car lat) a) (multirember a (cdr lat)))
>>    (else (cons (car lat) (multirember a (cdr lat))))))
>>    
>> scheme@(guile-user)> (multirember '(a b) '(x y (a b) z (a b)))
>> $1 = (x y z)
>> 
>> So why does guile return (x y z)? I expected (x y (a b) z (a b)). I know
>> eq? should only be used with symbols (and thus this example is more
>> theoretical) but nevertheless the return value is not right, since (eq?
>> '(a b) '(a b)) returns #f (Btw same in guile 2.0.11).
>
> Hm. As far as I know (eq? '(a b) '(a b)) is not *guaranteed* to evaluate
> to #f. The implementation might be free to re-use things it "knows" to be
> constant (I might be wrong, though).

Tomas is correct; within one compilation unit, constant literals will be
deduplicated.  That means that within one compilation unit, (eq? '(a b)
'(a b)) will indeed be #t.... yarggghhhh.... but:

  scheme@(guile-user)> (eq? '(a b) '(a b))
  $1 = #f
  scheme@(guile-user)> ,optimize (eq? '(a b) '(a b))
  $2 = #f

Evidently the optimizer is doing the compare at compile-time, which it
is allowed to do, and at compile-time the values are actually distinct.
I will see if I can fix that.  However Tomas' logic is impeccable :)

Closing as things are all working fine, I think.

Cheers,

Andy




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 23 Jul 2016 11:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 7 years and 272 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.