On Wed 08 Mar 2017 12:07, Alejandro Sanchez <hiph...@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