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") (DEFUN
FOO () ...)
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-name
cs-cl:intern
cs-cl:find-symbol
cs-cl:symbol-name
.cs-cl:shadow
cs-cl:find-all-symbols
cs-cl:string=
cs-cl:string/=
cs-cl:string<
cs-cl:string>
cs-cl:string<=
cs-cl:string>=
cs-cl:string-trim
cs-cl:string-left-trim
cs-cl:string-right-trim
SYMBOL
to a STRING
and therefore
exist in a variant that uses cs-cl:symbol-name
instead of SYMBOL-NAME
.cs-cl:make-package
PACKAGE
.
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) ⇒(
T
EQ
':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.93+ | Last modified: 2018-02-19 |