archives

Are first-class environments enough?

Everyone (e.g. in the LtU discussion back from 2010) seems to assume that first-class environments in a Scheme-like lexically scoped language are sufficient to implement all known module systems and then some. Still, it strikes me that implementing renaming of imported bindings (R[67]RS and Chicken (rename), Racket (rename-in)) with just first-class environments is impossible in the presence of mutability, even if foreign code is forbidden from mutating things inside the module. Even (only)-style shadowing is impossible without built-in support specifically for it in addition to plain environment inheritance. Introducing all this into environment semantics makes the whole idea look much less clean than it initially did. So, is this better done with stronger things like first-class locations? Or am I missing something obvious?

There are suggestions that MIT Scheme indeed implements its module system using environments, but I couldn’t really understand how (and whether) it handles this issue. The description in the Kernel language report is the best reference I could get on the topic.

Finally, note that this question is orthogonal to whether mutating exported bindings is a good thing to do from the stylistic point of view. If a language has mutability and a module system, it’d better be consistent in how they interact — a negative example here being the behaviour of bindings created with from module import ... in Python.