Что такое символ в схеме lisp/?

Для любви всемогущего мне еще предстоит понять цель символа 'iamasymbol. Я понимаю числа, булевы, строки... переменные. Но символы слишком велики для моего маленького императивного мышления. Для чего я их использую? Как они должны использоваться в программе? Мое понимание этой концепции просто терпит неудачу.

Ответ 1

В схеме и Racket символ похож на неизменяемую строку, которая оказывается интернированной, так что символы можно сравнивать с eq? (быстрое, по существу сравнение с указателем). Символы и строки являются отдельными типами данных.

Одно использование символов - это легкие перечисления. Например, можно сказать, что направление равно либо 'north, 'south, 'east, либо 'west. Разумеется, вы можете использовать строки с той же целью, но это будет немного менее эффективно. Использование чисел было бы плохой идеей; представлять информацию как можно более прозрачной и прозрачной.

В другом примере SXML представляет собой представление XML с использованием списков, символов и строк. В частности, строки представляют символьные данные, а символы представляют собой имена элементов. Таким образом, XML <em>hello world</em> будет представлен значением (list 'em "hello world"), которое может быть более компактно записано '(em "hello world").

Другое использование символов - это клавиши. Например, вы можете реализовать таблицу методов в качестве символов отображения словаря для функций реализации. Чтобы вызвать метод, вы просматриваете символ, соответствующий имени метода. Lisp/Scheme/Racket делает это очень просто, потому что язык уже имеет встроенную переписку между идентификаторами (часть синтаксиса языка) и символами (значения на языке). Эта переписка упрощает поддержку макросов, которые реализуют пользовательские синтаксические расширения для языка. Например, можно реализовать систему классов в виде библиотеки макросов, используя неявное соответствие между "именами методов" (синтаксическое понятие, определяемое системой классов) и символами:

(send obj meth arg1 arg2)
=>
(apply (lookup-method obj 'meth) obj (list arg1 arg2))

(В других Lisps, что я сказал, в основном это правда, но есть дополнительные вещи, о которых нужно знать, например, пакеты и функции с переменными слотами, IIRC.)

Ответ 2

Символ - это объект с простым строковым представлением, которое (по умолчанию) гарантировано интернировано; то есть любые два символа, которые записаны одинаково, являются одним и тем же объектом в памяти (ссылочное равенство).

Почему у Lisps есть символы? Ну, это в значительной степени артефакт того, что Lisps встраивают свой собственный синтаксис в качестве типа данных языка. Компиляторы и интерпретаторы используют символы для представления идентификаторов в программе; поскольку Lisp позволяет вам представлять синтаксис программы как данные, он предоставляет символы, потому что они являются частью представления.

Что они полезны помимо этого? Ну, несколько вещей:

  • Lisp обычно используется для реализации встроенных доменных языков. Многие из методов, используемых для этого, происходят из мира компилятора, поэтому символы здесь полезны.
  • Макросы в Common Lisp обычно включают обработку символов более подробно, чем дает этот ответ. (Хотя, в частности, генерация уникальных идентификаторов для расширений макросов требует возможности генерировать символ, который никогда не был бы равен любому другому.)
  • Исправленные типы перечисления лучше реализованы как символы, чем строки, потому что символы можно сравнивать по ссылочному равенству.
  • Есть много структур данных, которые вы можете построить, где вы можете получить выгоду от использования символов и ссылочного равенства.

Ответ 3

Символы в lisp являются человекочитаемыми идентификаторами. Все они одиночные. Поэтому, если вы объявляете "foo где-то в вашем коде, а затем снова используете" foo ", он укажет на то же место в памяти.

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

Ответ 4

Символ - это просто специальное имя для значения. Значение может быть любым, но этот символ используется для обозначения одного и того же значения каждый раз, и такого рода вещи используются для быстрого сравнения. Как вы говорите, вы сообразительны, они похожи на числовые константы в C, и именно так они обычно реализуются (внутренне сохраненные числа).

Ответ 5

Из структуры и интерпретации компьютерных программ Второе издание Гарольда Абельсона и Джеральда Джей Суссмана 1996:

Чтобы манипулировать символами, нам нужен новый элемент нашего языка: возможность процитировать объект данных. Предположим, мы хотим построить список (a b). Мы не можем выполнить это с помощью (список a), потому что это выражение строит список значений a и b, а не самих символов. Этот вопрос хорошо известен в контексте естественных языков, где слова и предложения могут рассматриваться как семантические сущности или как символ строки (синтаксические объекты). Обычная практика на естественных языках заключается в использовании кавычек, указывающих на то, что нужно лечить слово или предложение буквально как строка символов. Например, первая буква "Джон" - это ясно "J." Если мы скажем кому-то "произнести свое имя вслух", мы ожидаем услышать это человек имя. Однако, если мы скажем кому-то "произнести" ваше имя вслух, мы ожидаем услышать слова "твое имя". Обратите внимание, что мы вынуждены гнездиться кавычки для описания того, что кто-то может сказать.    Мы можем следовать этой же практике, чтобы идентифицировать списки и символы, которые для обработки как объектов данных, а не как выражений, подлежащих оценке.Однако наш формат цитирования отличается от формата естественных языков в что мы помещаем кавычку (традиционно, символ одиночной кавычки) только в начале объекта для цитирования. Мы можем уйти от этого в синтаксисе Схемы, потому что мы полагаемся на пробелы и круглые скобки, чтобы разграничить объекты. Таким образом, смысл символа одиночной кавычки заключается в цитировании следующий объект.   Теперь мы можем различать символы и их значения:

(define a 1)

(define b 2)

(list a b)
(1 2)

(list ’a ’b)
(a b)

(list ’a b)
(a 2)

Списки, содержащие символы, могут выглядеть так же, как выражения нашего языка:

(* (+ 23 45) (+ x 9)) 
(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))

Пример: Символическое дифференцирование