David Kastrup <d...@gnu.org> writes: > Bruce Korb <bk...@gnu.org> writes: > >>> sprintf(buf, "(define %s \"%s\")", "foo", my_str); >>> scm_eval_string(buf); >>> sprintf(buf, "(string-upcase! %s)", "foo") >>> // the string from my_str in "buf" is now scribbled over and completely gone >>> scm_eval_string(buf); >> >> Since I know the program I initially wrote (the define) is now gone, > > Why would a define be gone?
I think what Bruce means here is that, in theory, the string object created in the above `define' might have held a reference to part of his buffer `buf'. And indeed, we do make a copy of that buffer. So why not make a mutable copy? The reason is that, even though we make a copy of the program as we read it (converting from the string representation of `buf' into our internal representation), we'd like to be able to use the program multiple times. When I speak of the "program text", I'm not referring to the string representation of the program, but rather the internal representation. If we allow the user to unwittingly modify the program, it might work once but fail thereafter, as in: (define ten-spaces-with-one-star-at (lambda (i) (define s " ") (string-set! s i #\*) s)) Now, some reasonable people might say "Why arbitrarily limit the user? He might know what he's doing, and he might really want to do this!" Scheme provides a nice way to do this too: (define ten-spaces-with-new-star-at (let ((s (make-string 10 #\space))) (lambda (i) (string-set! s i #\*) s))) I normally lean toward assuming that the user knows what he's doing, but in this case I think Scheme got it right. Accidentally modifying literals is a very common mistake, and is almost never a good idea. If you want to make a program with internal mutable state, Scheme provides free variables, as used in the example above. Mark