guile-devel
[Top][All Lists]
Advanced

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

Re: Mutable top-level bindings


From: Ian Price
Subject: Re: Mutable top-level bindings
Date: Wed, 17 Apr 2013 21:25:13 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

"Chris K. Jester-Young" <address@hidden> writes:

> 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.

Not top-level, but _exports_ and _imports_. While their use is often
ugly, I'm not sure we should do away with all top level mutables.

Since I write a lot of R6RS code, I'm pretty used to the "no mutable
exports/imports" deal. It isn't too bothersome, except in some cases
with macros and so-called implicit exports/imports. (see bottom)

> 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.
It is pretty useful to be able to do redefinition in a different module
at the repl. Perhaps I could come up with a tortured argument to explain
why this is different from mutating a top-level export, but I'll refrain :)

> 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)))
+1

> 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))
This example is one that does not work in R6RS if you export foo, bar,
or baz. To do this, you need an additional set of defines that indirect
to the mutated ones.
e.g. https://github.com/rotty/spells/blob/master/spells/define-values.sls

>
> 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.
>


* Implicit imports/exports
(http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-10.html#node_sec_7.1)

"An exported macro may, however, implicitly export an otherwise
unexported identifier defined within or imported into the library. That
is, it may insert a reference to that identifier into the output code it
produces."

"All implicitly exported variables are also immutable in both the
exporting and importing libraries. It is thus a syntax violation if a
variable appears on the left-hand side of a set! expression in any code
produced by an exported macro outside of the library in which the
variable is defined...."

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



reply via email to

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