GNU bug report logs - #26026
Defining a method named zero? breaks primitive zero?

Previous Next

Package: guile;

Reported by: Alejandro Sanchez <hiphish <at> openmailbox.org>

Date: Wed, 8 Mar 2017 16:10:01 UTC

Severity: normal

Done: Andy Wingo <wingo <at> igalia.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 26026 in the body.
You can then email your comments to 26026 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#26026; Package guile. (Wed, 08 Mar 2017 16:10:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Alejandro Sanchez <hiphish <at> openmailbox.org>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Wed, 08 Mar 2017 16:10:02 GMT) Full text and rfc822 format available.

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

From: Alejandro Sanchez <hiphish <at> openmailbox.org>
To: bug-guile <at> gnu.org
Subject: Defining a method named zero? breaks primitive zero?
Date: Wed, 8 Mar 2017 12:07:56 +0100
If I define a ‘zero?’ predicate method for a custom class the primitive ‘zero?’ is lost. Here is a simple vector module:

	;;; File vector2.scm
	(define-module (vector2)
	  #:use-module (oop goops)
	  #:export (<vector2> get-x get-y zero?))
	
	(define-class <vector2> ()
	  (x #:init-value 0 #:getter get-x #:init-keyword #:x)
	  (y #:init-value 0 #:getter get-y #:init-keyword #:y) )

	(define-generic zero?)
	(define-method (zero? (v <vector2>))
	  (and (zero? (get-x v))
	       (zero? (get-y v))))

In the Guile REPL try executing the following code:

	scheme@(guile-user)> (use-modules (oop goops) (vector2))
	scheme@(guile-user)> (zero? (make <vector2>))

This will display 

	WARNING: (guile-user): `zero?' imported from both (ice-9 r5rs) and (vector2)
	ERROR: In procedure scm-error:
	ERROR: No applicable method for #<<generic> zero? (1)> in call (zero? 0)
	
	Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
	scheme@(guile-user) [1]> ,bt
	In vector2.scm:
	     11:7  2 (_ #<<vector2> 105e87e00>)
	In oop/goops.scm:
	   1438:4  1 (cache-miss 0)
	In unknown file:
	           0 (scm-error goops-error #f "No applicable method for ~S in call ~S" (#<<gen…> …) …)

Apparently the problem is that ‘zero?’ is defined in two modules and the vector2 definition overrides it. This isn’t the case with other primitives like ‘+’ or ‘*’, so this seems like a bug? I had built Guile from HEAD a few days ago, my package manager shows 6fff84d as the version number, so I guess that must be the hash of the commit HEAD was pointing to at that time.



Reply sent to Andy Wingo <wingo <at> igalia.com>:
You have taken responsibility. (Wed, 19 Apr 2017 15:13:02 GMT) Full text and rfc822 format available.

Notification sent to Alejandro Sanchez <hiphish <at> openmailbox.org>:
bug acknowledged by developer. (Wed, 19 Apr 2017 15:13:02 GMT) Full text and rfc822 format available.

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

From: Andy Wingo <wingo <at> igalia.com>
To: Alejandro Sanchez <hiphish <at> openmailbox.org>
Cc: 26026-done <at> debbugs.gnu.org
Subject: Re: bug#26026: Defining a method named zero? breaks primitive zero?
Date: Wed, 19 Apr 2017 17:12:12 +0200
On Wed 08 Mar 2017 12:07, Alejandro Sanchez <hiphish <at> openmailbox.org> writes:

> If I define a ‘zero?’ predicate method for a custom class the primitive ‘zero?’ is lost. Here is a simple vector module:
>
> 	;;; File vector2.scm
> 	(define-module (vector2)
> 	  #:use-module (oop goops)
> 	  #:export (<vector2> get-x get-y zero?))
> 	
> 	(define-class <vector2> ()
> 	  (x #:init-value 0 #:getter get-x #:init-keyword #:x)
> 	  (y #:init-value 0 #:getter get-y #:init-keyword #:y) )
>
> 	(define-generic zero?)
> 	(define-method (zero? (v <vector2>))
> 	  (and (zero? (get-x v))
> 	       (zero? (get-y v))))
>
> In the Guile REPL try executing the following code:
>
> 	scheme@(guile-user)> (use-modules (oop goops) (vector2))
> 	scheme@(guile-user)> (zero? (make <vector2>))
>
> This will display 
>
> 	WARNING: (guile-user): `zero?' imported from both (ice-9 r5rs) and (vector2)
> 	ERROR: In procedure scm-error:
> 	ERROR: No applicable method for #<<generic> zero? (1)> in call (zero? 0)
> 	
> 	Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> 	scheme@(guile-user) [1]> ,bt
> 	In vector2.scm:
> 	     11:7  2 (_ #<<vector2> 105e87e00>)
> 	In oop/goops.scm:
> 	   1438:4  1 (cache-miss 0)
> 	In unknown file:
> 	           0 (scm-error goops-error #f "No applicable method for ~S in call ~S" (#<<gen…> …) …)
>
> Apparently the problem is that ‘zero?’ is defined in two modules and
> the vector2 definition overrides it. This isn’t the case with other
> primitives like ‘+’ or ‘*’, so this seems like a bug? I had built
> Guile from HEAD a few days ago, my package manager shows 6fff84d as
> the version number, so I guess that must be the hash of the commit
> HEAD was pointing to at that time.

Actually the (vector2) module makes a fresh definition for zero?.  You
can tell because zero? is in its export list.  So instead of extending
the primitive-generic that is zero?, you are making a new definition.
See:

  scheme@(guile-user)> (define-module (foo) #:export (zero?))
  $1 = #<directory (foo) 1203c80>
  scheme@(foo)> (zero? 0)
  <unnamed port>:4:0: <unnamed port>:4:0: Unbound variable: zero?

  Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.

If you want to extend a primitive-generic, then do that by not exporting
zero?.  In a way it's like mutating the primitive in place, giving it
additional powers.

Andy




Information forwarded to bug-guile <at> gnu.org:
bug#26026; Package guile. (Sat, 22 Apr 2017 14:47:02 GMT) Full text and rfc822 format available.

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

From: Alejandro Sanchez <hiphish <at> openmailbox.org>
To: 26026 <at> debbugs.gnu.org
Subject: Re: bug#26026: closed (Re: bug#26026: Defining a method named zero?
 breaks primitive zero?)
Date: Sat, 22 Apr 2017 16:46:40 +0200
[Message part 1 (text/plain, inline)]
This does not work. If I remove the export of ‘zero?’ I get another error:

	scheme@(guile-user)>  (zero? (make <vector2>))
	<unnamed port>:3:1: <unnamed port>:3:1: In procedure =: Wrong type: #<<vector2> 106606e20>
	
	Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
	scheme@(guile-user) [1]> ,bt
	In current input:
	      3:1  0 (_)
	scheme@(guile-user) [1]>

That is why I was exporting ‘zero?’ to begin with. I do not have to export ‘+’ or ‘-‘ for example.

> On 19 Apr 2017, at 17:13, GNU bug Tracking System <help-debbugs <at> gnu.org> wrote:
> 
> Your bug report
> 
> #26026: Defining a method named zero? breaks primitive zero?
> 
> which was filed against the guile package, has been closed.
> 
> The explanation is attached below, along with your original report.
> If you require more details, please reply to 26026 <at> debbugs.gnu.org.
> 
> -- 
> 26026: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=26026
> GNU Bug Tracking System
> Contact help-debbugs <at> gnu.org with problems
> 
> From: Andy Wingo <wingo <at> igalia.com>
> Subject: Re: bug#26026: Defining a method named zero? breaks primitive zero?
> Date: 19 April 2017 at 17:12:12 GMT+2
> To: Alejandro Sanchez <hiphish <at> openmailbox.org>
> Cc: 26026-done <at> debbugs.gnu.org
> 
> 
> On Wed 08 Mar 2017 12:07, Alejandro Sanchez <hiphish <at> openmailbox.org> writes:
> 
>> If I define a ‘zero?’ predicate method for a custom class the primitive ‘zero?’ is lost. Here is a simple vector module:
>> 
>> 	;;; File vector2.scm
>> 	(define-module (vector2)
>> 	  #:use-module (oop goops)
>> 	  #:export (<vector2> get-x get-y zero?))
>> 	
>> 	(define-class <vector2> ()
>> 	  (x #:init-value 0 #:getter get-x #:init-keyword #:x)
>> 	  (y #:init-value 0 #:getter get-y #:init-keyword #:y) )
>> 
>> 	(define-generic zero?)
>> 	(define-method (zero? (v <vector2>))
>> 	  (and (zero? (get-x v))
>> 	       (zero? (get-y v))))
>> 
>> In the Guile REPL try executing the following code:
>> 
>> 	scheme@(guile-user)> (use-modules (oop goops) (vector2))
>> 	scheme@(guile-user)> (zero? (make <vector2>))
>> 
>> This will display 
>> 
>> 	WARNING: (guile-user): `zero?' imported from both (ice-9 r5rs) and (vector2)
>> 	ERROR: In procedure scm-error:
>> 	ERROR: No applicable method for #<<generic> zero? (1)> in call (zero? 0)
>> 	
>> 	Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
>> 	scheme@(guile-user) [1]> ,bt
>> 	In vector2.scm:
>> 	     11:7  2 (_ #<<vector2> 105e87e00>)
>> 	In oop/goops.scm:
>> 	   1438:4  1 (cache-miss 0)
>> 	In unknown file:
>> 	           0 (scm-error goops-error #f "No applicable method for ~S in call ~S" (#<<gen…> …) …)
>> 
>> Apparently the problem is that ‘zero?’ is defined in two modules and
>> the vector2 definition overrides it. This isn’t the case with other
>> primitives like ‘+’ or ‘*’, so this seems like a bug? I had built
>> Guile from HEAD a few days ago, my package manager shows 6fff84d as
>> the version number, so I guess that must be the hash of the commit
>> HEAD was pointing to at that time.
> 
> Actually the (vector2) module makes a fresh definition for zero?.  You
> can tell because zero? is in its export list.  So instead of extending
> the primitive-generic that is zero?, you are making a new definition.
> See:
> 
>  scheme@(guile-user)> (define-module (foo) #:export (zero?))
>  $1 = #<directory (foo) 1203c80>
>  scheme@(foo)> (zero? 0)
>  <unnamed port>:4:0: <unnamed port>:4:0: Unbound variable: zero?
> 
>  Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> 
> If you want to extend a primitive-generic, then do that by not exporting
> zero?.  In a way it's like mutating the primitive in place, giving it
> additional powers.
> 
> Andy
> 
> 
> 
> 
> From: Alejandro Sanchez <hiphish <at> openmailbox.org>
> Subject: Defining a method named zero? breaks primitive zero?
> Date: 8 March 2017 at 12:07:56 GMT+1
> To: bug-guile <at> gnu.org
> 
> 
> If I define a ‘zero?’ predicate method for a custom class the primitive ‘zero?’ is lost. Here is a simple vector module:
> 
> 	;;; File vector2.scm
> 	(define-module (vector2)
> 	  #:use-module (oop goops)
> 	  #:export (<vector2> get-x get-y zero?))
> 	
> 	(define-class <vector2> ()
> 	  (x #:init-value 0 #:getter get-x #:init-keyword #:x)
> 	  (y #:init-value 0 #:getter get-y #:init-keyword #:y) )
> 
> 	(define-generic zero?)
> 	(define-method (zero? (v <vector2>))
> 	  (and (zero? (get-x v))
> 	       (zero? (get-y v))))
> 
> In the Guile REPL try executing the following code:
> 
> 	scheme@(guile-user)> (use-modules (oop goops) (vector2))
> 	scheme@(guile-user)> (zero? (make <vector2>))
> 
> This will display 
> 
> 	WARNING: (guile-user): `zero?' imported from both (ice-9 r5rs) and (vector2)
> 	ERROR: In procedure scm-error:
> 	ERROR: No applicable method for #<<generic> zero? (1)> in call (zero? 0)
> 	
> 	Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> 	scheme@(guile-user) [1]> ,bt
> 	In vector2.scm:
> 	     11:7  2 (_ #<<vector2> 105e87e00>)
> 	In oop/goops.scm:
> 	   1438:4  1 (cache-miss 0)
> 	In unknown file:
> 	           0 (scm-error goops-error #f "No applicable method for ~S in call ~S" (#<<gen…> …) …)
> 
> Apparently the problem is that ‘zero?’ is defined in two modules and the vector2 definition overrides it. This isn’t the case with other primitives like ‘+’ or ‘*’, so this seems like a bug? I had built Guile from HEAD a few days ago, my package manager shows 6fff84d as the version number, so I guess that must be the hash of the commit HEAD was pointing to at that time.
> 
> 
> 

[Message part 2 (text/html, inline)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 21 May 2017 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 6 years and 334 days ago.

Previous Next


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