[ERR5RS] Bindings in R5RS vs R6RS

Jonathan A Rees jar at mumble.net
Sat Sep 15 18:01:47 PDT 2007


On Sep 15, 2007, at 3:39 PM, David Rush wrote:
...
> And to be fair to the immutability argument - I am unaware of any
> Scheme which truly implements mutable bindings for things like CAR,
> MAP, or APPEND. Under the covers of every toplevel are the internal
> names of the actual primitives which implement the ur-CAR, ur-MAP, and
> ur-APPEND functionality that is required to make *everything* work.
> However, this *fact* actually proves the earlier point, IMO. The names
> of the primitives are not relevant - the algebra provided by category
> of the functions and data *is*.

Scheme48 implements immutable bindings, but also has an interactive  
model. I think you should know how it works, not as a "proposal" but  
as a design point and for comparison.

A structure is a set of bindings exported from some environment. The  
values can only be modified (set!) by code evaluated in that  
environment. An evaluation environment not inside any local binding  
constructs (lambda, let, etc.) has in effect two layers: An outer  
immutable 'frame' that is the union of a bunch of structures, and an  
inner frame in which define puts its bindings. You can set! the  
latter. The latter can also shadow anything that's imported from a  
structure.

For r5rs, there is a 'scheme' structure, which is not special in any  
way, and that's the only one that's imported. set! of car is an error  
if you haven't defined car. Try it.

The static compilation semantics is pretty clear: it is possible to  
infer immutability of exported bindings, and then rely on them in  
compiling client modules. So we get cross-module integration with  
almost no kludgery and almost no declaration (you do have to set a  
flag saying that you're on your own if you want to diddle with  
integrated bindings, or something like that - sort of like 'sealing'  
in found in some dynamic languages - there may be better ways to do  
this).

This all works well enough that we were able to do embedded  
programming in Scheme48 with no 'mode' change in the system. If you  
didn't ask for EVAL or other trickery, then it didn't take up space  
in the EPROM.

There is no clear or principled interaction semantics, but I think  
there could be with some work. You can't set! imported bindings, but  
you can always shadow them. If you haven't permitted integration then  
this always does something perfectly clear and, importantly, in  
keeping with R5RS. (Scheme48 is slavish to R5RS, or has been so far.)

To make interaction work, the system does allow additions to variable  
export lists and structure import sets, and strives to make  
everything appear to be totally dynamic.

I do agree that you want to be able to do meta-programming in Scheme,  
since the meta-programming is going to happen in any case, and if the  
right tools aren't given in Scheme then other tools will be found to  
do the job, such as bash, make, sed, perl, etc.  That should be  
enough to terrify any implementation into supporting EVAL and all  
other dynamic operations. Scheme48 doesn't really implement this  
philosophy. But to really replace the ugly tools is a tall order. In  
particular it doesn't work to have a global module namespace since  
you often have to use one configuration (set of module versions) to  
manipulate another.

Jonathan



More information about the Err5rs mailing list