CLISP supports programs written with case sensitive symbols. For
example, with case sensitive symbols, the symbols cdr
(the function equivalent to REST) and the symbol CDR
(a user-defined type denoting a Call Data Record) are different and unrelated.
There are some incompatibilities between programs assuming case
sensitive symbols and programs assuming the [ANSI CL standard] case insensitive symbols.
For example, (eq 'KB 'Kb) evaluates to false in a case
sensitive world and to true in a case insensitive world. However, unlike some
commercial Common Lisp implementations, CLISP allows both kinds of programs to
coexist in the same process and interoperate with each other. Example:
OLD.lisp(IN-PACKAGE"OLD") (DEFUNFOO () ...)
modern.lisp
(in-package "NEW")
(defun bar () (old:foo))
(symbol-name 'bar) ; ⇒ "bar"
This is achieved through specification of the symbol case policy at the package level. A modern package is one that is declared to be both case-sensitive and case-inverted and which use the symbols from the “CS-COMMON-LISP” package.
A case-sensitive package
is one whose DEFPACKAGE declaration (or MAKE-PACKAGE
creation form) has the option (.
In a case-sensitive package, the reader does not uppercase the
symbol name before calling :CASE-SENSITIVE T)INTERN. Similarly, the printer, when
printing the SYMBOL-NAME part of a SYMBOL (i.e. the part after
the package markers), behaves as if the readtable's case were set
to :PRESERVE.
See also Section 11.1.5, “Function EXT:PACKAGE-CASE-SENSITIVE-P”.
A case-inverted package
is one whose DEFPACKAGE declaration (or MAKE-PACKAGE
creation form) has the option (.
In the context of a case-inverted package, symbol names are
case-inverted: upper case characters are mapped to lower case, lower
case characters are mapped to upper case, and other characters are left
untouched. Every symbol thus conceptually has two symbol names: an
old-world symbol name and a modern-world symbol name, which is the
case-inverted old-world name. The first symbol name is returned by the
function :CASE-INVERTED T)SYMBOL-NAME, the modern one by the
function cs-cl:symbol-name. The internal
functions for creating or looking up symbols in a package, which
traditionally took a string argument, now conceptually take two string
arguments: old-style-string and inverted-string. Actually, a function
like INTERN takes the old-style-string as argument and computes the
inverted-string from it; whereas the
function cs-cl:intern takes the inverted-string as
argument and computes the old-style-string from it.
See also Section 11.1.4, “Function EXT:PACKAGE-CASE-INVERTED-P”.
For a few built-in functions, a variant for the case-inverted world is defined in the “CS-COMMON-LISP” package, which has the nickname “CS-CL”:
cs-cl:symbol-namecs-cl:interncs-cl:find-symbolcs-cl:symbol-name.cs-cl:shadowcs-cl:find-all-symbolscs-cl:string=cs-cl:string/=cs-cl:string<cs-cl:string>cs-cl:string<=cs-cl:string>=cs-cl:string-trimcs-cl:string-left-trimcs-cl:string-right-trimSYMBOL to a STRING and therefore
exist in a variant that uses cs-cl:symbol-name
instead of SYMBOL-NAME.cs-cl:make-packagePACKAGE.
A package “CS-COMMON-LISP-USER” is provided for the user to modify and work in. It plays the same role as “COMMON-LISP-USER”, but for the case-sensitive world.
The handling of package names is unchanged. Package names are
still usually uppercase. The package names are also subject to
(.READTABLE-CASE *READTABLE*)
Note that gensyms and keywords are still treated traditionally: even in a case-sensitive package,
(STRING='#:FooBar '#:foobar) ⇒(TEQ':KeyWord ':keyword) ⇒T
We believe this has a limited negative impact for the moment, but can be changed some time in the future.
The following practices will pose no problems when migrating to a modern case-sensitive world:
(STRING= (SYMBOL-NAME x) (SYMBOL-NAME y)).
The following practices will not work in a case-sensitive world or can give problems:
SYMBOL-NAME return values with EQ.
(SYMBOL-NAME x) with
(cs-cl:symbol-name y).CLISP supports a command-line option -modern that
sets the *PACKAGE* initially to the “CS-COMMON-LISP-USER” package, and
*PRINT-CASE* to :DOWNCASE.
For packages to be located in the “modern”
(case-sensitive) world, you need to augment their DEFPACKAGE
declaration by adding the option (,
see Section 11.1.2, “Macro :MODERN T)DEFPACKAGE”.
| These notes document CLISP version 2.49 | Last modified: 2010-07-07 |