bug-guile
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#19459: #:export does not honor the merge-generics contract


From: David Pirotte
Subject: bug#19459: #:export does not honor the merge-generics contract
Date: Thu, 23 Jun 2016 16:23:21 -0300

Hi Andy,

> > (define-module (a)
> >   #:use-module (oop goops)
> >   #:export (<a>
> >         !width
> >         get-width
> >         set-width))  

> Here you export four bindings: one class and three generics.  Those
> three generics have methods on <a>.

> > (define-module (b)
> >   #:use-module (oop goops)
> >   #:use-module (a)  

> Here you import the previous four bindings.

> >   #:export (<b>
> >         !width
> >         get-width
> >         set-width))  

> However here you declare that you are going to export four new
> bindings.
> ...

Under the exact circumstances of the original email, I disagree, see below.

        From the original email, you only kept the module defs and explains 
here in your
        answer the expected behavior in normal circumstances: the behavior one 
can
        expect from the default Guile configuration. Fine, but that's not the 
what
        the original email was complaining about :)

> AFAIU there is no bug here.  David WDYT?

IMO it is a bug, and to be honest, IMO it is a serious one: a user should never 
have
to use #:re-export for generic functions once he/she did ask to merge duplicate
generics, because under this setting, there can be 1 and only 1 generic 
function, at
any time in any module. Under these circumstances, it is the generic function 
as the
module 'sees it' that the user export, not the generic function as the module 
sees
it before import(s)

        if imported, then that generic is 'filled in' with new methods, it is 
_not_
        created [should not be created], hence #:export is the 'culprit', 
because as
        it is it does not look if a generic exists and create a new one 
arbitrarily,
        against the user 'wish'. It can only do so if there is no imported one.

So, IMO, under the '(merge-generics ...) setting of the original email (b) 
exports 1
new binding and 3 generic functions that were already defined by (a), but/and
'filled' with 3 additional methods. The module (b) exports the generic function 
'as
it has it'.

There is another way, maybe, to look at this anomaly: if you comment the export 
for
get-width and set-width from the (b) module, it works:

        scheme@(guile-user)> ,use (b)
        scheme@(guile-user)> (make <b>)
        $4 = #<<b> 2051a40>

because within the module (b), the generics set-width and get-width were 
imported
from (a), not created [or 'immediately' merged, implementation detail...], and 
filed
with the (b) methods. #:export however dismantle this to export a new generic 
[but
the user ask to merge them, so it breaks the user 'contract'] only containing 
the (b)
methods, which is a bug.

Last but not least, when a user imports (b) and run (make <b>), he is not 
himself
calling set-width or get-width: exported or not, the code being run by make 
should
run within the (b) module, and in the (b) module the generic functions have been
merged,, so can not [should] raise an error. If you follow your idea/position, 
it
should only raise an error if I do (get-width (make <a>)) [but then the system 
might
raise the undefined <a> class first..., but you get the idea I guess.

FIWIW, It's been years that I don't use #:export because of this bug, I defined 
my
own g-export syntax, based on guile's module source code, here:

        http://git.savannah.gnu.org/cgit/grip.git/tree/grip/g-export.scm

It would be really good if it be fixed in 2.0.12 and master though.

Cheers,
David

Attachment: pgpFT2eYaGf80.pgp
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]