[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new function or modify read



>>>>> "Marc" == Marc Feeley <feeley@xxxxxxxxxxxxxxxx> writes:

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.

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

I did read what you wrote.  I wrote 

>> So PARAMETERIZE has the wrong semantics to enforce what you're
>> suggesting, and there's too much potential for foot-shooting.

Note the word "enforce."

Marc> Of course you can shoot yourself in the foot if your new code does
Marc> (parameterize (...) (some-other-function-than-write)).  

Exactly.  This is why PARAMETERIZE is the wrong mechanism for this:
it's a mechanism for dynamic assignment, when what the mechanism we
really need is lexical in nature.

Marc> This is a problem with your new code.  Your old code is still
Marc> "correct".  The same issue exists with "with-output-to-file".
Marc> If your old code was sending some output to the current output
Marc> port to interact with the user, then a

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

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

Except you know exactly in advance how DISPLAY/WRITE without an
explicit port specification interact with WITH-OUTPUT-FILE.  You're
suggesting we put stuff we *don't know yet* into the parameters.
Also, the current output port is something completely different in
nature, namely that it's actually useful to redirect output within a
dynamic extent.  This just isn't true with the output options for
WRITE.

Marc> Dynamic scoping is powerful, just like recursion, continuations,
Marc> threads, exceptions, etc.  You have to use them with care.

Which is why it's a good thing to use restricted (suitable)
abstractions when applicable.

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

Right.  But then I wasn't addressing those.

-- 
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla