Hi :)

On Sun 24 Nov 2019 18:54, Ludovic Courtès <l...@gnu.org> 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