2011-12-19 13 views
14

Co oznacza składnia, dwukropki poprzedzające zmienną w Common Lisp? Widziałem programy z takimi, a ja przedstawię tutaj przykładowy kod z dużego zestawu funkcji.Dlaczego dwukropki poprzedzają zmienne w 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)) 
    )) 

Odpowiedz

18

To nie są zmienne; to są słowa kluczowe. Są specjalnym rodzajem skutecznego tokena, podobnego do "atomów" w innych językach. Jest to wygodny, wbudowany sposób przekazywania parametrów nazwanych (i prawie zawsze opcjonalnych) do wywołania funkcji.

http://www.gigamonkeys.com/book/functions.html opisuje składnię wywołań funkcji.

27

Złożone Symbole

:foo jest keyword symbol.

  • internowany i wywożone z opakowania KEYWORD
  • ciągle związana sobie

Zastosowanie

symbole Złożone są stosowane, gdy trzeba kombinację następujących właściwości:

  • symbolem jest właściwa struktura danych
  • symbole o tej samej nazwie powinna być unikalna (przez internowania ich w opakowaniu) -> pakiet KEYWORD
  • różne pakiety nie są potrzebne lub chciał -> pakiet KEYWORD
  • pisanie symbol powinny być proste, nie wymagające do ich zacytować ->:foo lepiej niż ':foo
  • zdolność do działania jako zmienna z różnymi wartościami nie jest potrzebne ->:foo:foo ocenia się sam i tylko :foo

W Common Lisp ogólnie symbole mogą znajdować się w pakiecie (rodzaj przestrzeni nazw).

Niesportowany symbol bar w opakowaniu foo jest napisany jako foo::bar. Podwójny dwukropek znajduje się między nazwą pakietu a nazwą symbolu.

Wyeksportowany symbol zostanie zapisany jako foo:bar. Użyty jest pojedynczy dwukropek.

Jeśli symbol jest dostępny w aktualnym pakiecie, jest on zapisany jako bar bez opakowania.

Pakiet KEYWORD

Istnieje specjalny pakiet o nazwie KEYWORD. Symbol bar w tym pakiecie jest po prostu i zawsze pisany jako :bar.

Przykłady

Symbole te słowa kluczowe mają również te interesujące właściwości: symbole są automatycznie eksportowane z pakietu KEYWORD (tak keyword::bar, keyword:bar, ::bar i :bar są takie same symbol) i ocenią do siebie:

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 

Wykorzystanie

symbole Złożone są stosowane na przykład w wymienionych nazw argumenty

(defun foo (&key bar) (+ bar 10)) 

(foo :bar 7) 

Zazwyczaj są one również stosowane w argumenty przykład i budowę konstrukcji.

(defstruct node state parent action) 

DEFSTRUCT jest Common Lisp makro i generuje kilka funkcji. Jednym z nich jest funkcja MAKE-NODE, który może być używany jako:

(make-node :state 'open 
      :parent some-parent 
      :action an-action) 

Uwaga: czasami dane mogą być również kluczowe. Na przykład w powyższym formularzu, państwo może być :open i nie open:

(make-node :state :open 
      :parent some-parent 
      :action an-action) 
+0

Piszesz: „An ** wyeksportowany symbol ** ... jest napisane jak' foo. Bar' * Pojedyncza okrężnicy służy * .. "a także" symbole [słowa kluczowego] są ** automatycznie eksportowane **, "ale twój przykład pokazuje' (eq 'keyword: bar': bar) '. Dlaczego używasz dwukropka, jeśli słowa kluczowe są zawsze eksportowane? Czy można używać '::' z symbolami wyeksportowanymi i nie eksportowanymi? –

+0

@GlennSlayden Tak, każdy internowany symbol, eksportowany lub nie eksportowany, może być zapisany jako pakiet :: nazwa. Tylko wyeksportowane symbole można zapisać jako pakiet: nazwa. Tylko symbole słów kluczowych można zapisać jako: imię. –

+0

Dla kompletności, co z ':: bar'? Czy w dalszym ciągu odnosi się do pakietu "KEYWORD", czy może byłaby to inna forma globalna? Przepraszamy za bycie nowicjuszem LISP. –