melisgl / named-readtables

The official repo of named-readtables.
Other
66 stars 15 forks source link

Export READTABLE= #16

Closed phoe closed 3 years ago

phoe commented 4 years ago

Recently we've rediscovered a long-standing ASDF issue where libraries may modify the global readtable. It can be reproduced easily on Quicklisp via (ql:quickload :qtools) (named-readtables:in-readtable :qtools) (asdf:load-system :esrap :force t)

The idea is to have ASDF check and warn/error/cerror if a system modifies the global readtable. Obviously, that would break many libraries and make Stas really angery, which is why we first want to check which Quicklisp systems mutate the global readtable. This will allow us to file issues in the proper places and ask the maintainers to patch their stuff and use named-readtables instead.

The checking requires a function that compares two readtables for equality. There is one at https://github.com/melisgl/named-readtables/blob/master/test/tests.lisp#L48-L53 - is there a chance for it to be documented and properly exported?

melisgl commented 4 years ago

Here is an example tree that is being compared in the linked function:

((#\" #<FUNCTION SB-IMPL::READ-STRING> NIL)
 (#\# #<CLOSURE (LAMBDA (STREAM CHAR) :IN SB-IMPL::%MAKE-DISPATCH-MACRO-CHAR) {1003D4042B}> T 
      ((#\Backspace . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\Tab . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\Newline . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\Page . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\Return . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\  . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\# . #<FUNCTION SB-IMPL::SHARP-SHARP>)
       (#\' . #<FUNCTION SB-IMPL::SHARP-QUOTE>)
       (#\( . #<FUNCTION SB-IMPL::SHARP-LEFT-PAREN>)
       (#\) . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\* . #<FUNCTION SB-IMPL::SHARP-STAR>)
       (#\+ . #<FUNCTION SB-IMPL::SHARP-PLUS-MINUS>)
       (#\- . #<FUNCTION SB-IMPL::SHARP-PLUS-MINUS>)
       (#\. . #<FUNCTION SB-IMPL::SHARP-DOT>)
       (#\: . #<FUNCTION SB-IMPL::SHARP-COLON>)
       (#\< . #<FUNCTION SB-IMPL::SHARP-ILLEGAL>)
       (#\= . #<FUNCTION SB-IMPL::SHARP-EQUAL>)
       (#\A . #<FUNCTION SB-IMPL::SHARP-A>)
       (#\B . #<FUNCTION SB-IMPL::SHARP-B>)
       (#\C . #<FUNCTION SB-IMPL::SHARP-C>)
       (#\O . #<FUNCTION SB-IMPL::SHARP-O>)
       (#\P . #<FUNCTION SB-IMPL::SHARP-P>)
       (#\R . #<FUNCTION SB-IMPL::SHARP-R>)
       (#\S . #<FUNCTION SB-IMPL::SHARP-S>)
       (#\X . #<FUNCTION SB-IMPL::SHARP-X>)
       (#\\ . #<FUNCTION SB-IMPL::SHARP-BACKSLASH>)
       (#\| . #<FUNCTION SB-IMPL::SHARP-VERTICAL-BAR>)))
 (#\' #<FUNCTION SB-IMPL::READ-QUOTE> NIL)
 (#\( #<FUNCTION SB-IMPL::READ-LIST> NIL)
 (#\) #<FUNCTION SB-IMPL::READ-RIGHT-PAREN> NIL)
 (#\, #<FUNCTION SB-IMPL::COMMA-CHARMACRO> NIL)
 (#\; #<FUNCTION SB-IMPL::READ-COMMENT> NIL)
 (#\` #<FUNCTION SB-IMPL::BACKQUOTE-CHARMACRO> NIL))

I'm wary of exposing READTABLE=, due to function redefinition changing object identity in terms of EQ. For example, after recompiling a library, the readtable it redefines will likely not be READTABLE= to new readtable. As a check to detect undesirable behaviour, I suggest using the unexported READTABLE=, but note it does not compare READTABLE-CASE.