Reader Case (Upcasing)
rontolisp's reader upcases symbols the way standard Common Lisp's does: every
unescaped character of a symbol token is converted to upper case while
reading (the :upcase readtable case), so foo, Foo and FOO in source
all name the same symbol FOO. Escaped characters keep their case:
|mixed Case| and \( read verbatim.
The upcased name is the canonical one -- there is no fold back to a lowercase
spelling. Standard names, t/nil, lambda-list markers and built-in package
members are all upper case like everything else:
- standard
clnames (defunandDEFUNboth read asDEFUN,listasLIST), including type-specifier and condition-type names (HASH-TABLE,TYPE-ERROR), T/NIL/PIand the other read-time constants,- lambda-list markers (
&OPTIONAL,&KEY, ...), - built-in package prefixes and their members (
rl:fetchreads asRL:FETCH,ql:quickloadasQL:QUICKLOAD), - keyword or
#:designators ((in-package :cl-user)reads:CL-USER,(:use #:cl)reads#:CL).
Your symbols, your packages and your data keywords upcase the same way, self-consistently, exactly like Common Lisp:
An escaped name keeps its case and is therefore a distinct symbol from the
upcased one, as in Common Lisp: |car| is not CAR.
Built-in keyword parameters match case-insensitively (:TEST works where
:test does), and (intern "TIME") names the standard TIME, so the
(intern (string-upcase ...)) name-synthesis idiom lines up with body
references, the pattern behind macros like assoc-utils' with-keys:
$ cat keys.lisp
(ql:quickload :assoc-utils)
(print (assoc-utils:with-keys ("name") '(("name" . "eitaro"))
name))
$ rontolisp keys.lisp
"eitaro"
Libraries loaded with load, asdf:load-system or ql:quickload are read
the same way, so their definitions and your references upcase consistently.
A symbol system designator is downcased like ASDF's coerce-name
((ql:quickload :ASSOC-UTILS) finds the assoc-utils system).
The runtime reader upcases too, so a datum read at run time behaves like the
same datum written in source: read and read-from-string upcase your
symbols identically on the interpreter, the JVM and both WASM backends.
Printing back: *print-case*
The printer writes the stored (upper-case) spelling, which is what
*print-case*'s standard value :upcase says. Binding the variable converts
the case of every symbol a printing operator spells -- princ, prin1,
print, princ-to-string, prin1-to-string, write-to-string, write and
the ~A / ~S format directives -- on the interpreter, the JVM and both WASM
backends:
Only symbols convert: a string keeps its own characters, a character prints as
itself, and nil / t are symbols and do convert. :capitalize keeps each
word's first character as it stands and downcases the rest of the word (a word
is a run of alphanumerics); it never upcases a lower-case character, because the
standard converts only the upper-case ones -- which is where the rule parts
company with string-capitalize.
Deviation: a symbol nested inside a structure, a CLOS instance, a hash table or an array of rank other than one keeps its stored spelling. The conversion walks lists and vectors and hands those containers to the ordinary renderer.
Deviations from Common Lisp
intern,make-symbolandfind-symboltake the name verbatim (there is no separate intern table; a symbol is its name).(find-symbol "car")isNILbecause the standard symbol is named"CAR", and(make-symbol "X")twice yieldseqsymbols. Reading is unaffected --carin source still upcases toCAR.- A keyword or
#:designator that spells a member in mixed case names that exact (mixed-case) symbol; write built-in members upper case (#:CL) or let the reader upcase a bare name.