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

Issue: READ-CASE-SENSITIVITY (Version 4)



Mostly this still looks ok to me.  I will certainly encourage Moon to
vote Yes on it. But I do have a few comments which I think would both
improve the presentation and would help us avoid confusions down the
road...

    Date: Thu, 22 Jun 89 19:32:17 BST
    From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSFnet-Relay.AC.UK>

    Maybe this is OK.  If anyone has objections, I'd really like to hear
    them before everyone goes off to the meeting.  (Um, I know it's rather
    late.)

    Issue:        READ-CASE-SENSITIVITY
    ...
    Proposal (READ-CASE-SENSITIVITY:READTABLE-KEYWORDS)
    ...
      The READTABLE-CASE of a readtable also has significance when
      printing.  The case in which letters are printed is determined as
      follows:

        When READTABLE-CASE is :UPCASE, upper-case letters are printed
        in the case specified by *PRINT-CASE*, and lower-case letters
        are printed in their own case.

        When READTABLE-CASE is :DOWNCASE, lower-case letters are printed
        in the case specified by *PRINT-CASE*, and upper-case letters
        are printed in their own case.

        When READTABLE-CASE is :PRESERVE, all letters are printed in their
        own case.

        When READTABLE-CASE is :INVERT, the case of all letters in single-
        case symbol names is inverted.  Mixed-case symbol names are printed
        as-is.

      (The behavior when *PRINT-CASE* is :CAPITALIZE is like :UPCASE for
      the first character and :DOWNCASE for the rest.)
      ...

I think this parenthetic remark is more confusing than helpful.
For example, it only applies in the cases of READTABLE-CASE
being :UPCASE or :DOWNCASE, right? Strictly, I think it is not
necessary because the phrase "in the case specified by *PRINT-CASE*"
means this. If you really feel the remark is needed, I suggest the
notation:

  The READTABLE-CASE of a readtable also has significance when
  printing.  The case in which letters are printed is determined as
  follows:

    When READTABLE-CASE is :UPCASE, upper-case letters are printed
    in the case specified by *PRINT-CASE* [1], and lower-case letters
    are printed in their own case.

    When READTABLE-CASE is :DOWNCASE, lower-case letters are printed
    in the case specified by *PRINT-CASE* [1], and upper-case letters
    are printed in their own case.

    When READTABLE-CASE is :PRESERVE, all letters are printed in their
    own case.

    When READTABLE-CASE is :INVERT, the case of all letters in single-
    case symbol names is inverted.  Mixed-case symbol names are printed
    as-is.

  [1] That is, :UPCASE means uppercase, :DOWNCASE means lowercase,
      and :CAPITALIZE means uppercase for the first character and
      lowercase for the rest of the characters.
  ...

   -----
    Test Case:

       (let ((rt (copy-readtable nil)))
        (mapcar
          #'(lambda (case)
              (setf (readtable-case rt) case)
              (read-from-string "Zebra"))
          '(:upcase :downcase :preserve :invert)))

        => (ZEBRA |zebra| |Zebra| |zEBRA|) ;as printed with the standard
                                           ;readtable and *print-case* :upcase

This example is buggy, of course, because you need to bind *READTABLE*, not RT.
It's also incomplete because it doesn't explain the interaction with *PRINT-CASE*.

It would be better if we had a test case which at least did:

(let ((*readtable* (copy-readtable nil))
      (*print-case* *print-case*)
      (readtable-cases '(:upcase :downcase :preserve :invert))
      (print-cases '(:upcase :downcase :capitalize)))
  (format t "READTABLE-CASE *PRINT-CASE*        ZEBRA Zebra zebra zEBRA~
	   ~%----------------------------------------------------------~
	   ~%")
  (dolist (readtable-case readtable-cases)
    (dolist (print-case print-cases)
      (let ((data '()))
	(setf (readtable-case *readtable*) readtable-case)
	(setq *print-case* print-case)
	(dolist (string '("ZEBRA" "Zebra" "zebra" "zEBRA"))
	  (push (read-from-string string) data))
	(setq data (nreverse data))
	(setf (readtable-case *readtable*) readtable-case)
	(format t "~&:~A~16T:~A~32T   ~{~A~â?? ~}"
		(string-upcase readtable-case)
		(string-upcase print-case)
		data)))))

Actually, a full table like the following might be even clearer, but maybe
that's overkill...

(let ((*readtable* (copy-readtable nil))
      (*print-case* *print-case*)
      (readtable-cases '(:upcase :downcase :preserve :invert))
      (print-cases '(:upcase :downcase :capitalize)))
  (format t "READTABLE-CASE          *PRINT-CASE*   Input:~
           ~%Read        Print       Print          ZEBRA Zebra zebra zEBRA~
	   ~%--------------------------------------------------------------~
	   ~%")
  (dolist (readtable-case-for-read-time readtable-cases)
    (dolist (readtable-case-for-print-time readtable-cases)
      (dolist (print-case-for-print-time print-cases)
	(let ((data '()))
	  (setf (readtable-case *readtable*) readtable-case-for-read-time)
	  (dolist (string '("ZEBRA" "Zebra" "zebra" "zEBRA"))
	    (push (read-from-string string) data))
	  (setq data (nreverse data))
	  (setf (readtable-case *readtable*) readtable-case-for-print-time)
	  (setq *print-case* print-case-for-print-time)                
	  (format t "~&:~A~12T:~A~24T:~A~36T   ~{~A~â?? ~}"
		  (string-upcase readtable-case-for-read-time)
		  (string-upcase readtable-case-for-print-time)
		  (string-upcase print-case-for-print-time)
		  data))))))