Почему двоеточия предшествуют переменным в 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)