Re: new function or modify read Marc Feeley 18 Dec 2002 17:52 UTC

> Marc>   (parameterize ((write-shared #t)
> Marc>                  (write-radix 16)
> Marc>                  (write-prettily #t))
> Marc>     (write X))
> >>
> >> Except your old code doesn't know anything about the presence of all
> >> these flags.  In fact, every new feature controlled via these
> >> parameters might break the old code.
>
> Marc> Could you explain why?  I explicitly said: "But this will not happen
> Marc> if you code your calls to write in this style: ...", meaning that only
> Marc> "write" is in the scope of the parameterize.  There is no old code
> Marc> affected by the parameterize!
>
> Yes, there is, namely if you have this in new code ...
>
> (parameterize ((write-symbols-all-lower-case #t))
>   (old-code-procedure))
>
> ... and this in old code:
>
> (define (old-code-procedure)
>   (write (string->symbol "FooBarBaz")))
>
> So PARAMETERIZE has the wrong semantics to enforce what you're
> suggesting, and there's too much potential for foot-shooting.

Please read what I wrote.  Only "write" is in the scope of
"parameterize" in new code.

Of course you can shoot yourself in the foot if your new code does
(parameterize (...) (some-other-function-than-write)).  This is a
problem with your new code.  Your old code is still "correct".  The
same issue exists with "with-output-to-file".  If your old code was
sending some output to the current output port to interact with the
user, then a

   (with-output-to-file "foo" (lambda () (old-code-procedure)))

will suddenly malfunction (the user interaction output will go to the
file).

Dynamic scoping is powerful, just like recursion, continuations,
threads, exceptions, etc.  You have to use them with care.  In this
particular case, use the style (parameterize (...)
(some-other-function-than-write)) carefully.

The chances of shooting yourself in the foot is greatly minimized
when you use my last suggestion (using readtables and port specific
readtable parameter objects).

Marc