11.5. Package Case-Sensitivity
Prev | Chapter 11. Packages | Next

## 11.5. Package Case-Sensitivity

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 `(`:CASE-SENSITIVE` `T`)`. In a case-sensitive package, the reader does not uppercase the symbol name before calling `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 `(`:CASE-INVERTED` `T`)`. 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 `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`
  returns the case-inverted symbol name.
`cs-cl:intern`
`cs-cl:find-symbol`
  work consistently with `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`
  convert a `SYMBOL` to a `STRING` and therefore exist in a variant that uses `cs-cl:symbol-name` instead of `SYMBOL-NAME`.
`cs-cl:make-package`
  creates a case-inverted `PACKAGE`.

### 11.5.1. User Package for the Case-sensitive World

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.

### 11.5.2. Package Names

The handling of package names is unchanged. Package names are still usually uppercase. The package names are also subject to `(`READTABLE-CASE` `*READTABLE*`)`.

### 11.5.3. Gensyms and Keywords

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.

### 11.5.4. Migration Tips

The following practices will pose no problems when migrating to a modern case-sensitive world:

- Using [ANSI CL standard] symbols in lowercase.
- Macros that create symbols by suffixing or prefixing given symbols.
- Comparing symbol names as in `(`STRING=` (`SYMBOL-NAME` `x`) (`SYMBOL-NAME` `y`))`.

The following practices will not work in a case-sensitive world or can give problems:

- Accessing the same symbol in both upper- and lowercase from the same source file.
- Macros that create symbols in other packages than the original symbols.
- Comparing `SYMBOL-NAME` return values with `EQ`.
- Comparing `(`SYMBOL-NAME` x)` with `(cs-cl:symbol-name y)`.

### 11.5.5. Using case-sensitive packages by default

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 `(`:MODERN` `T`)`.

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
11.4. Implementation-Defined Packages | Home | Chapter 12. Numbers