[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