Come creare: parole chiave?


16

Q: Come si crea e si usa :keywords?

Prendi in considerazione un tentativo (apparentemente ingenuo) di accedere alla seguente lista dei giocattoli:

(setf alist '((:key-1 "Key no. 1")
              (:key-2 "Key no. 2")))

(assq :key-1 alist)                 ; => (:key-1 "Key no. 1")
(assq (make-symbol ":key-1") alist) ; => nil

La prima chiave funziona come previsto, ma la seconda chiave no. Nella misura in cui non esiste una make-keywordfunzione ovvia , come si crea e si usa una parola chiave?

Motivazione originale: devo trasformare una stringa in una chiave di ricerca che è un simbolo sul quale posso putproprietà.

Nel processo di formulazione di questa domanda, ho ottenuto almeno una parte della risposta, che sto postando separatamente. Spero che menti più brillanti delle mie possano migliorarla.


1
(eq :foo (read ":foo"))
abo-ABO

Risposte:


9

Hai ragione nel make-symbolcreare una parola chiave diversa da quella eqesistente e che internpotrebbe inquinare l'obarray globale con il nuovo simbolo. Tra questi, hai intern-soft, che restituisce il simbolo se è già stato creato o nilse non ha:

ELISP> (intern-soft ":key-1")
nil
ELISP> :key-1
:key-1
ELISP> (intern-soft ":key-1")
:key-1

Questo dovrebbe essere adatto al tuo scopo: se la parola chiave non esiste, non può essere presente nella lista, quindi non è necessario crearla solo per verificare se è presente. Qualcosa di simile a:

(let ((maybe-keyword (intern-soft ":key-1")))
  (and maybe-keyword (assq maybe-keyword alist)))

Intelligente - avevo visto intern-softma non avevo pensato di usarlo in questo modo.
Dan

6

Forse non capisco correttamente la domanda. Ma se si vuole una parola chiave (ad esempio, si desidera soddisfare keywordp), allora si desidera che il simbolo da internato nel obarray globale , obarray.

Si deve essere internato lì per soddisfare keywordp, AFAICT, e C-h f keywordpdice così.

Quindi la risposta alla tua domanda, AFAICT, è solo da usareintern .

Sento che forse non stai facendo la tua vera domanda - sembra una domanda XY. Cosa stai davvero cercando di fare? (Forse ponilo come una domanda separata.)

[In risposta al tuo commento che il interning " non è :keywordspecifico, in quanto si applica a tutti i simboli ": Corretto, il interning non è specifico per le parole chiave. Ma internare (in obarray) e usare un symbol-nameche inizia con :è specifico per le parole chiave.]


È certamente una domanda XY nel senso che sto cercando di Y, ma mi sono davvero interessato a X nel mio tentativo di arrivare a Y. Consentitemi di riflettere su come porre la domanda su Y in modo tale che sia utile anche agli altri.
Dan

Grande. Questo sarà utile. Grazie.
Estratto il

2

Ecco una risposta parziale a questa domanda. La versione breve e non del tutto soddisfacente sembra essere: usare intern.

:key-1 soddisfa entrambi:

(symbolp :key-1)                    ; => t
(keywordp :key-1)                   ; => t

Mentre (make-symbol ":key-1")soddisfa il primo ma non il secondo:

(symbolp (make-symbol ":key-1"))    ; => t
(keywordp (make-symbol ":key-1"))   ; => nil

Ora, la dotstring per make-symboldice che sarà:

Restituisce un simbolo non assegnato appena assegnato il cui nome è NAME.

Mmmkay, e la dotstring per keywordpdice che sarà:

Ritorna tse OBJECT è una parola chiave. Ciò significa che è un simbolo con un nome di stampa che inizia con : internato nell'obarray iniziale.

Quindi sembra che internfunzionerà:

(assq (intern ":key-1") alist)      ; => (:key-1 "Key no. 1")

Perché internsarà:

Restituisce il simbolo canonico il cui nome è STRING. Se non ce n'è, uno viene creato da questa funzione e restituito. Un secondo argomento facoltativo specifica l'obarray da usare; il valore predefinito è obarray.

Ma questo non sembra essere :keywordspecifico, in quanto si applica a tutti i simboli. Per impostazione predefinita, sembra anche inquinare il globale obarray, che può essere o meno un grosso problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.