Почему двоеточия предшествуют переменным в Common Lisp
что означает синтаксис, двоеточия, предшествующие переменной в Common Lisp? Я видел программы с такими, и я представлю здесь пример кода из большого набора функций.
(defun expand (successorf node)
(mapcar (lambda (action-state-cost)
(let ((action (car action-state-cost))
(state (cadr action-state-cost))
(cost (caddr action-state-cost)))
(make-node :state state :parent node
:action action :path-cost (+ (node-path-cost node) cost)
:depth (1+ (node-depth node)))
))
(funcall successorf (node-state node))
))
2 ответов
на самом деле это не переменные; это ключевые слова. Это особый вид эффективного токена, похожий на" атомы " в других языках. Это удобный, встроенный способ передачи именованных (и почти всегда необязательных) параметров в вызов функции.
http://www.gigamonkeys.com/book/functions.html описывает синтаксис вызовов функций.
Символы Ключевых Слов
:foo
это ключевое слово символ.
- интернирован и экспортирован из
KEYWORD
пакета - постоянно привязан к себе
использование
символы ключевых слов используются, когда требуется сочетание следующих свойств:
- символ-это правильные данные структура
- символы с тем же именем должны быть уникальными (путем интернирования их в пакет) -> пакет
KEYWORD
- разные пакеты не нужна -> пакет
KEYWORD
- написание символа должно быть легко, не нужно цитировать их ->
:foo
лучше, чем':foo
- возможность действовать как переменная с разными значениями не требуется ->
:foo
значение:foo
себе и только к:foo
в Common Lisp обычно символы могут находиться в пакете (своего рода пространстве имен).
несообщаемый символ bar
в пакете foo
написано foo::bar
. Двоеточие находится между именем пакета и именем символа.
экспортированный символ затем записывается как foo:bar
. Используется один двоеточие.
если символ доступен в текущем пакете, то записывается как bar
без пакет.
пакета KEYWORD
есть специальный пакет под названием KEYWORD
. Символ bar
в этом пакете просто и всегда пишется как :bar
.
примеры
эти символы ключевых слов также имеют следующие интересные свойства: символы автоматически экспортируются из пакета KEYWORD
(т. keyword::bar
, keyword:bar
, ::bar
и :bar
все тот же символ) и они оценивают в сами:
CL-USER 5 > :bar
:BAR
CL-USER 6 > (describe :bar)
:BAR is a SYMBOL
NAME "BAR"
VALUE :BAR
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The KEYWORD package, 0/4 internal, 5830/8192 external>
CL-USER 7 > (eq 'keyword::bar ':bar)
T
CL-USER 8 > (eq :bar ':bar) ; quoted or unquoted, each subform evaluates to :bar
T
использование
символы ключевых слов используются, например, как имена в именованных аргументах:
(defun foo (&key bar) (+ bar 10))
(foo :bar 7)
обычно они также используются в аргументах для создания экземпляра и структуры.
(defstruct node state parent action)
DEFSTRUCT
является общим макросом Lisp и генерирует несколько функций. Одна из них-функция MAKE-NODE
, который можно использовать как:
(make-node :state 'open
:parent some-parent
:action an-action)
Примечание: иногда данные также могут быть ключевым словом. Например, в приведенной выше форме состояние может быть :open
, а не open
:
(make-node :state :open
:parent some-parent
:action an-action)