This is not a direct answer for your problem, but a description of the
mess you've gotten yourself into which eventually got to that problem,
and will lead to other problems too.
I'll try to first explain how Racket evaluates a module very briefly,
since it'll be relevant to understanding the mess. It looks like you're
trying to use "just scheme" so you're probably not too interested in
this, but you should still read it to understand the problems you're in.
(Even if you solved that particular one.)
In the usual case of .rkt files each file is evaluated in its own
namespace, which is populated by bindings from (1) the #lang that you
specify, and (2) various libraries (= other modules) that you require.
So when you have
#lang foo
(require bar)
you start from a fresh namespace, grab all of the bindings from foo
into this namespace, and then you add the bindings from bar. In case
of clashes, the require bindings will shadow ones from the language,
so if both of them provided some function f, the name that your code
will use will be the one from bar. If you require more than one
library:
#lang foo
(require bar baz)
and both bar and baz provide f, then you'll get an error if
these are different fs. This can happen if, for example, bar
provides the builtin cons and baz provides a cons that creates
mutable pairs (ie, provides the builtin mcons as cons). You will
not get an error if both of them provide the same f though.
Again, note that this is different from the "initial bindings" which is
what you get from the #lang -- a latter require will just shadow
them if the same name is used. The reason for the #lang bindings
treated differently is that they provide some basic bindings that the
code uses at a fundamental level. For example, the language bindings
will get you the require that you use later on. Another example is a
#%module-begin macro that wraps the whole module body -- a tool that
can be used to transform all expressions into something else, for
example, this is how toplevel expressions in the racket language get
their value printed.
Roughly speaking, libraries (= modules) in racket are split into
language modules and library modules. This is not something that is
formal since both are implemented in the same way: modules that provide
stuff. The difference is in the kind of stuff that they provide, where
language modules will usually provide lots of bindings, include basic
ones like require and #%module-begin, and things that you expect
from a lispish language like define, if, cond, +, cons, etc.
In the usual case, therefore, you don't run into problems of name
clashes too much since libraries try to avoid common names. But if you
try to require a language module as if its a library, you very quickly
run into such problems since language modules tend to provide lots of
names, including those very common names like the ones I listed above.
Now you can see how this is a problem in your code0.scm:
#lang scheme
(require rnrs/base-6)
(require rnrs/mutable-pairs-6)
what this does is use the scheme bindings first. This scheme
language is not standard scheme -- it's the precursor to the racket
language, dating to before the name change when Racket was known as PLT
Scheme, and therefore scheme was intended to be "the scheme dialect
that PLT Scheme uses by default". Among other things, it has immutable
pairs, same as the ones you get in #lang racket files.
But later on you pile up most of the rnrs bindings -- and those use
mutable pairs, which are, as you've discovered, a different type.
You're requiring a module that is usually used as a language, so most
of the bindings you use will work fine, but sooner or later you'll run
into a binding from scheme that is not shadowed by one from rnrs,
and if it's something that has to do with pairs, you'll get problems.
So the conclusion here is to avoid mixing up two languages like this:
either stick to #lang scheme or to #lang r6rs. In the former case,
you can just as well switch to #lang racket, and use the usual racket
libraries, and in the latter case you should be careful and try to avoid
importing racket libraries that expect immutable pairs (and more).
Alternatively, if your goal is to do some SICP, then use the SICP
language that Neil Van Dyke
wrote.
But you have more problems, still. In your code_1.scm you're using
scheme/load as the language, and that's something that might make it
possible to do what you're trying to do -- but it brings with it a whole
pile of other problems. I you look up the documentation for
scheme/load (which will send you to the docs for racket/load, the
more modern name), you'll see some stuff about eval and load. This
is because at some point people wanted to be able to write a single file
that has several modules in it, but that was not possible. (Now it is,
and you get submodules -- but racket/load is still kept around.)
scheme/load was implemented to address this: using it is as if you're
entering expressions in a single REPL, so you can define a bunch of
modules and use them. But it's an odd language because of this, and if
you don't want that particular feature, you should avoid it.
The load in the name is something that should have actually been
something that discourages people from using it... The thing is that
load is an old and primitive tool for structuring code, which was the
only available thing in the standard language up to R5RS. The thing
that it does is (again, this is a rough description) read expressions
from a file and evaluate them. The problem is that you get a single
namespace for everything, and worse, each definition can actually be a
mutation of a previous definition if one existed. This means that even
simple definitions like
(define (add1 x) (+ 1 x))
are not safe, since a later load of a file can redefine + in a way
that breaks this definition. In short, this is very much a mess in a
world where many libraries provide you with the same names but with
different semantics. IOW, it's usually a mess in Racket. Racket (and
later, R6RS) uses modules in a way that sorts the whole thing out in a
much better way -- there's no single namespace and mutation, just names
that are provided from closed modules. Actualy, the mutation thing is
still there, but it is more restricted in the damage you can get (it's
used only in the REPL); and load is there too, together with eval,
and they are generally avoided as tools to organize source files.
Using load also explains why you had to remove the #lang line when
you've used it -- when you load a file with a module definition, you
get just that definition -- the module's. To actually use the things
that the module provides, you'd also need to add a (require 'code_0).
Yet another thing is that dropping the #lang line is usually a
disaster since you're left without the necessary bindings for any
reasonable piece of code -- but in your case, you required a whole
language later on, which is how things continued to work, only with
subtle differences.
So the second highlevel conclusion is to avoid load -- it's a bad
tool. Also, avoid the scheme/load or racket/load languages unless
you really know what they're doing and need that functionality.