Subject: Re: (setf (readtable-case *readtable*) :invert) completely preserves symbol case in CMUCL
From: Erik Naggum <erik@naggum.net>
Date: Sun, 26 May 2002 17:42:04 GMT
Newsgroups: comp.lang.lisp
Message-ID: <3231423721764115@naggum.net>

* Adam Warner <usenet@consulting.net.nz>
| Yes I have achieved enlightenment Erik.

  You made my day!

| I can't use preserve because none of the built in functions can be called
| using lower case.  Perhaps a custom compiled CMUCL image would be a long
| term solution.

  Well, that way lies madness.  One Common Lisp vendor has decided to make
  a "custom" world in which symbols are in their preferred lower-case.
  While I also like to read and see lower-case, all I need to do to get
  that most of the time is with either :invert or :upcase and *print-case*
  to :downcase.  However, if you want to use lower-case names in your own
  code, you can shadow intern, find-symbol, and symbol-name to invert their
  argument.  Efficient invertion is not necessarily a trivial task, and
  your implementation may have optimized functions for it, but this is a
  shot, and intended to be an efficien tone.  Just how efficient it is
  seems to vary a lot between implementations:

(defun invert-string (string)
  (declare (optimize (speed 3) (safety 0))
	   (simple-string string))
  (check-type string 'string)
  (prog ((invert nil)
	 (index 0)
	 (length (length string)))
    (declare (simple-string invert)
	     (type (integer 0 65536) index length))
   unknown-case
    (cond ((= index length)
	   (return string))
	  ((upper-case-p (schar string index))
	   (when (and (/= (1+ index) length)
		      (lower-case-p (schar string (1+ index))))
	     (return string))
	   (setq invert (copy-seq string))
	   (go upper-case))
	  ((lower-case-p (schar string index))
	   (setq invert (copy-seq string))
	   (go lower-case))
	  (t
	   (incf index)
	   (go unknown-case)))
   upper-case
    (setf (schar invert index) (char-downcase (schar invert index)))
    (incf index)
    (cond ((= index length)
	   (return invert))
	  ((lower-case-p (schar invert index))
	   (return string))
	  (t
	   (go upper-case)))
   lower-case
    (setf (schar invert index) (char-upcase (schar invert index)))
    (incf index)
    (cond ((= index length)
	   (return invert))
	  ((upper-case-p (schar invert index))
	   (return string))
	  (t
	   (go lower-case)))))
-- 
  In a fight against something, the fight has value, victory has none.
  In a fight for something, the fight is a loss, victory merely relief.

  70 percent of American adults do not understand the scientific process.