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

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

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

Ответы

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

* (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 противоположна по умолчанию, преобразуя все в нижний регистр, не давая вам никакой чувствительности к регистру.

Но с :invert символы, которые вы пишете в исходном коде, например defun, setf функцию hi, преобразуются в верхний регистр, а любой символ в 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

Ответ 3

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

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

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

Ответ 4

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