I don't find the behavior strange. 1. Declaring dialog generic in mg-1 and mg-2 and merge generics in mg-3 solves the mg-3 case.
2. When exporting dialog in mg-4 the system automatically undefine the dialog symbol imported. By in stead using :re-export (dialog) the mg-4 case is solved. The question if we should automatically always merge generics and automatically always define accessors generic I do not agree. The reason is that the current approach is more general. On the other hand as we saw subtle bugs can appear and a good warning/diagnosing system that can help pinpoint these issues would indeed be a good additions. /Stefan On Thursday, February 21, 2013 07:51:39 PM David Pirotte wrote: > Hello all, > > given the following 4 modules, I am facing what I consider an > inconsistent goops behavior and have one problem which leads to my > recurrent request of goops default behavior should be to [a] always > create a generic function for accessors and methods that do not [yet] > have one, visible in the entire guile space [all modules] and [b] the > default behavior should be '(merge-generics replace warn-override-core > warn last) [but that at least that one I can set using :duplicate, I > know] > > so, 2 or 3 things to show what happens and see what developers think. > > > 1] > > if i use in the repl or in my init.scm > > (default-duplicate-binding-handler '(merge-generics replace > warn-override-core warn last)) > > -> > > david@capac:~/gnu/kise 14 $ guile > GNU Guile 2.0.7.9-21982 > ... > scheme@(guile-user)> (default-duplicate-binding-handler > '(merge-generics replace warn-override-core warn last)) > scheme@(guile-user)> (use-modules (mg-3)) > (mg3/letstry) > > ;;; note: source file /usr/alto/projects/gnu/tests/mg-3.scm > ;;; newer than compiled > /home/david/.cache/guile/ccache/2.0-LE-8-2.0/usr/alto/projects/gnu/te > sts/mg-3.scm.go ;;; note: auto-compilation is enabled, set > GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument > to disable. ;;; compiling /usr/alto/projects/gnu/tests/mg-3.scm > WARNING: (mg-3): `dialog' imported from both (mg-1) and (mg-2) > ;;; compiled > /home/david/.cache/guile/ccache/2.0-LE-8-2.0/usr/alto/projects/gnu/te > sts/mg-3.scm.go WARNING: (mg-3): `dialog' imported from both (mg-1) > and (mg-2) ERROR: In procedure scm-error: > ERROR: No applicable method for #<<accessor> dialog (1)> in call > (dialog #<<widget-a> 1e97660>) > > > 2] > > if I uncomment the :duplicates block in mg-3, then it's fine > > ... ... > ;;; ("widget-a:" dialog-a) > > ;;; ("widget-b:" dialog-b) > scheme@(guile-user)> > > > 3] > > what is more of a problem with the existing goops default, for me, is > expressed in the mg-4.scm 'case': i can not make it work unless I > manually create another module, manually making generics and make sure > it is loaded before ... or rename the accessors, which both solutions > are really against my expectation and [long] CLOS practice: why > should I have to manually do things which are inherent to oop [same > name for slots pertaining to different classes is so common that i > can not see any large application not having to do so, for semantic > reasons]. > > unless i did miss that there is a way to ask goops to create a generic > fucntion for accessors and methods per default ? > > > scheme@(guile-user)> (use-modules (mg-4)) > ;;; note: source file /usr/alto/projects/gnu/tests/mg-4.scm > ;;; newer than compiled > /home/david/.cache/guile/ccache/2.0-LE-8-2.0/usr/alto/projects/gnu/te > sts/mg-4.scm.go ;;; note: auto-compilation is enabled, set > GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument > to disable. ;;; compiling /usr/alto/projects/gnu/tests/mg-4.scm > ;;; compiled > /home/david/.cache/guile/ccache/2.0-LE-8-2.0/usr/alto/projects/gnu/te > sts/mg-4.scm.go scheme@(guile-user)> (mg4/letstry) > ERROR: In procedure scm-error: > ERROR: No applicable method for #<<accessor> dialog (1)> in call > (dialog #<<widget-a> 23b7a60>) > > > > ;; cheers > cheers :) > David > > > > ;;mg-1.scm > > (define-module (mg-1) > > :use-module (oop goops) > : > :export (<widget-a> > > dialog > make-widget-a)) > > (define-class <widget-a> () > (dialog #:accessor dialog #:init-keyword #:dialog #:init-value #f)) > > (define (make-widget-a) > (make <widget-a> #:dialog 'dialog-a)) > > > ;; mg-2.scm > > (define-module (mg-2) > > :use-module (oop goops) > : > :export (<widget-b> > > dialog > make-widget-b)) > > > (define-class <widget-b> () > (dialog #:accessor dialog #:init-keyword #:dialog #:init-value #f)) > > (define (make-widget-b) > (make <widget-b> #:dialog 'dialog-b)) > > > ;; mg3.scm > > (define-module (mg-3) > > :use-module (oop goops) > : > :use-module (mg-1) > :use-module (mg-2) > > #! > > :duplicates (merge-generics > > replace > warn-override-core > warn > last) > !# > > :export (mg3/letstry)) > > (define (mg3/letstry) > (pk "widget-a:" (dialog (make-widget-a))) > (pk "widget-b:" (dialog (make-widget-b))) > (values)) > > > ;; mg-4.scm > > (define-module (mg-4) > > :use-module (oop goops) > :use-module (mg-1) > : > :duplicates (merge-generics > > replace > warn-override-core > warn > last) > > :export (<widget-b> > > dialog > make-widget-b > mg4/letstry)) > > (define-class <widget-b> () > (dialog #:accessor dialog #:init-keyword #:dialog #:init-value #f)) > > (define (make-widget-b) > (make <widget-b> #:dialog 'dialog-b)) > > (define (mg4/letstry) > (pk "widget-a:" (dialog (make-widget-a))) > (pk "widget-b:" (dialog (make-widget-b))))