Для любви всемогущего мне еще предстоит понять цель символа 'iamasymbol
. Я понимаю числа, булевы, строки... переменные. Но символы слишком велики для моего маленького императивного мышления. Для чего я их использую? Как они должны использоваться в программе? Мое понимание этой концепции просто терпит неудачу.
Что такое символ в схеме lisp/?
Ответ 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)))))
Пример: Символическое дифференцирование