guile-devel
[Top][All Lists]
Advanced

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

Re: Mutating public bindings of a declarative module


From: Andy Wingo
Subject: Re: Mutating public bindings of a declarative module
Date: Mon, 25 Nov 2019 09:33:16 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux)

Hi :)

On Sun 24 Nov 2019 18:54, Ludovic Courtès <address@hidden> writes:

> It seems that if you ‘set!’ a public variable of a declarative module,
> the change is visible to all the module users, but it’s not necessarily
> visible to procedures within that module, presumably because they use an
> inlined or specialized variant of that thing.
>
> I would have imagined that public bindings are considered mutable and
> thus not subject to inlining; OTOH, that would obviously be a loss, so
> the current approach makes sense.

Right, I understand the frustration.  For what it is worth, I think we
have the right default for what it means to be a declarative module, but
I'm definitely open to having that conversation.

> Anyway, it complicates a use case for me.  In Guix, we “mock” bindings
> like so:
>
>   (define-syntax-rule (mock (module proc replacement) body ...)
>     "Within BODY, replace the definition of PROC from MODULE with the 
> definition
>   given by REPLACEMENT."
>     (let* ((m (resolve-interface 'module))
>            (original (module-ref m 'proc)))
>       (dynamic-wind
>         (lambda () (module-set! m 'proc replacement))
>         (lambda () body ...)
>         (lambda () (module-set! m 'proc original)))))
>
> and that allows us to write tests that temporarily modify public (or
> private!) bindings.
>
> It seems like this could be addressed by compiling selected modules with
> ‘user-modules-declarative?’ set to #false, or by avoiding the above hack
> altogether when possible, but I thought I’d share my impressions and
> listen to what people think.  :-)

This works.  (Actually the way I would do it is to pass #:declarative?
#f in the define-module for the modules in question.)  Marking some
bindings as not declarative also works (e.g. (set! foo foo)).

For me the most robust solution would be to have `mock' verify that the
module it's funging isn't declarative.  We don't currently have a way to
know if an individual module binding is declarative or not (though we
could add this).

Cheers,

Andy



reply via email to

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