Почему Common Lisp нечувствителен к регистру?

есть ли преимущество в определении функции, такой как (defun hi () "Hi!") и иметь возможность вызвать его с помощью (hi) или (HI) или (Hi) или (setf a-number 5) и иметь доступ к этому номеру, используя a-number, A-NUMBER или A-Number?

если есть такое преимущество, то почему большинство других чувствительны к регистру языков?

4 ответов


использование чувствительных к регистру имен в коде в интерактивном сеансе просто более подвержено ошибкам.

Common Lisp чувствителен к регистру. Это просто, что общая функциональность чтения Lisp по умолчанию преобразует все символы без эскиза символов в верхний регистр. Это также определено в стандарте Common Lisp. Предопределенные общие символы Lisp также все заглавные внутри.

использование верхнего регистра было распространено на старых машинах. Помните, что дизайн Common Lisp начался в начале восьмидесятых (1982) и целью была совместимость с более ранним Maclisp и когда было больше типов компьютеров для поддержки (например, так называемые мини-компьютеры и мэйнфреймы). Другие языки программирования, используемые на старых компьютерах, также используют идентификаторы верхнего регистра, такие как COBOL или PL/1.

также обратите внимание, что Lisp часто использовался интерактивно, так что во время сеанса интерактивного программирования получить правильный случай имен сложнее. Это немного легче, когда Lisp reader использует регистр по умолчанию (здесь верхний регистр) и преобразует все входные данные в этот регистр.

Common Lisp поддерживает другие режимы чтения, и вы также можете избежать символов:|This is a Symbol with mixed CASE and spaces|.

сегодня много программного обеспечения, либо в нижнем регистре или даже регистр со строчной предпочтительным. Некоторые поставщики Lisp предоставляют нестандартный вариант Common Lisp, где все символы по умолчанию строчные, а считыватель сохраняет регистр. Но это делает его несовместимым со стандартным Common Lisp, где ожидается, что (symbol-name 'cl:defun) Это "сайт defun", а не "сайт defun".


для интерактивных сессий, в случае unsensitivity используется по умолчанию, когда общий стандарт Лиспа был определен.

но на самом деле происходит то, что общий читатель Lisp преобразует все символы в upcase перед интернированием и оценкой. Это по умолчанию, но вы всегда можете изменить его, если хотите.

на *readtable* объекты имеют атрибут,readtable-case, который контролирует, как читатель интернов и оценивает символы чтения. вы можете setf readtable-case до :upcase(по умолчанию), :downcase, :preserve, :invert.

по умолчанию readtable-case установлено значение :upcase, что приводит к преобразованию всех символов в upcase.

если вы хотите, чтобы чувствительность к регистру, вы должны сделать

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

на первый взгляд, вы можете подумать, что было бы лучше выбрать вариант :Сохранить, но у него есть небольшая проблема: все символы, определенные стандартом, должны быть обновлены. Таким образом, у вас будет чувствительность к регистру символы, определенные только вами, и должны были бы написать:

* (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

на :downcase опция противоположна умолчанию, Преобразуя все в downcase,не давая вам чувствительности к регистру.

но с :invert символы, которые вы пишете в исходном коде, как defun, setf the hi функция, преобразуется в upcase и любой символ в CamelCase сохраняется, как это изначально:

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

(как указывали другие, на самом деле он чувствителен к регистру, но стандартное поведение читателя-это все.)

как преимущество:

  • вы действительно хотите Hashtable и HashTable называть разные вещи?
  • поскольку Common Lisp предоставляет разные пространства имен, вам также не нужна капитализация, чтобы различать имена классов, переменных и функций (среди прочих). Вы можете иметь класс name и name без двусмысленность. Name может быть даже имя переменной, поверх этого.
  • как видно из последнего предложения, вы можете заглавными буквами имен символов в прозе, как и любые другие слова.

по умолчанию считыватель в CL преобразует регистр, все экранированные символы превращаются в верхний регистр. Вы можете настроить это поведение с помощью readtable-case. Это потому, что его легко взаимодействовать с другими языками, которые следуют тем же соглашениям.