Why is Common Lisp case insensitive?

后端 未结 4 1283
日久生厌
日久生厌 2020-12-09 09:41

Is there an advantage to defining a function like (defun hi () \"Hi!\") and be able to call it by using (hi) or (HI) or (Hi)

4条回答
  •  醉酒成梦
    2020-12-09 10:22

    For interactive sessions, the case unsensitivity used to be the default when the Common Lisp standard was defined.

    But, what truly happens is that the Common Lisp reader converts all symbols to upcase before interning and evaluating it. That is the default, but you can always change it if you want.

    The *readtable* objects has an attribute, readtable-case, that controls how the reader interns and evaluates the symbols read. you can setf readtable-case to :upcase(default), :downcase, :preserve, :invert.

    By default, the readtable-case is set to :upcase, which causes all symbols to be converted to upcase.

    If you want case sensitivity, you should do

    (setf (readtable-case *readtable*) :invert)
    => :invert
    

    At a first glance, you might think that it would be better to choose the :preserve option, but it has some minor issue: all the symbols, as defined by the standard, must be upcased. So, you would have case sensitivity to the symbols defined by you only, and would have to do write:

    * (DEFUN hi () "Hi!")
    => hi
    * (SETF a-number 5)
    => a-number
    * (HI)
    => ;error: the stored function is #'HI in the *readtable*, but by 
       ;       calling (HI) you try to acces a function named #'hi(downcase), which
       ;       gives an error
    * A-NUMBER
    => ;error: same for the variable
    * (hi)
    => "Hi!"
    * a-number
    => 5
    

    The :downcase option is the opposite of the default, converting everything to downcase, giving you no case sensitivity.

    But with :invert, the symbols you write in the source code, like defun, setf the hi function, get converted to upcase, and any symbol in CamelCase is preserved like it is originaly:

    * (setf (readtable-case *readtable*) :invert)
    => :invert
    * (defun Hi () "Hi!")
    => Hi
    * (Hi)
    => "Hi!"
    * (eq 'Hi 'hi)
    => nil
    * (eq 'HI 'hi)
    => nil
    * (eq 'Hi 'Hi)
    => t
    

提交回复
热议问题