On Mon, Apr 15, 2013 at 10:00:55PM -0400, Mark H Weaver wrote: > Unfortunately, this is rarely possible in a language like Scheme, where > calls to procedures bound by mutable top-level variables are frequent. > We cannot fix this without making most commonly-used top-level bindings > immutable. Last I checked, there was strong resistance to this idea.
Maybe it's time to reopen this (and hope it's not a can of worms). :-) With a proper module system, I don't see why top-level bindings should be mutable. That would make even things like direct inlining of cons or + somewhat harder than it needs to be. The way I understand it, the definition of (@ (guile) cons) or the like should not be subject to change at runtime. If people want to change the behaviour of cons, write a module that replaces the top-level binding. Yes, this does disable the ability to perform monkey-patching. I don't see this as a big loss, but perhaps there are legitimate use cases for monkey-patching that I haven't thought of. Another thing we will need to provide is define-values, which allows you to make top-level bindings that are mutually-recursive. By which I mean: (define-values (foo bar baz) (letrec ((foo ...) (bar ...) (baz ...)) (values foo bar baz))) This would obviate the need to use the following pattern: (define foo #f) (define bar #f) (define baz #f) (letrec ((my-foo ...) (my-bar ...) (my-baz ...)) (set! foo my-foo) (set! bar my-bar) (set! baz my-baz)) Granted, there are existing modules that use that approach currently, as we don't currently have define-values. But I think it should be possible to annotate individual modules as having immutable top-level bindings, so that we can gradually migrate modules to the define-values style. Cheers, Chris.