2012-07-12 11 views
11

Ecco il problema: non riesco a "ottenere" gli espansori di espansione e vorrei imparare come funzionano.definizione di espansioni di espansione in Common Lisp

ho bisogno di imparare come funzionano perché ho un problema che sembra un tipico esempio del motivo per cui si dovrebbe imparare setf-espansori, il problema è il seguente:

(defparameter some-array (make-array 10)) 

(defun arr-index (index-string) 
    (aref some-array (parse-integer index-string)) 

(setf (arr-index "2") 7) ;; Error: undefined function (setf arr-index) 

Come faccio a scrivere un adeguato setf-expander per ARR-INDEX?

risposta

15
(defun (setf arr-index) (new-value index-string) 
    (setf (aref some-array (parse-integer index-string)) 
     new-value)) 

In Common Lisp un function name non può essere solo un simbolo, ma anche un elenco di due simboli con SETF come il primo simbolo. Vedi sopra. DEFUN quindi può definire le funzioni SETF. Il nome della funzione è (setf arr-index).

Un setf funzione può essere utilizzato in un luogo forma: CLHS: Other compound forms as places.

Il nuovo valore è quindi il primo argomento.

CL-USER 15 > some-array 
#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) 

CL-USER 16 > (setf (arr-index "2") 7) 
7 

CL-USER 17 > some-array 
#(NIL NIL 7 NIL NIL NIL NIL NIL NIL NIL) 
+0

Non riuscivo a trovarlo nel CLHS, dov'è? –

+0

@Nowhereman: http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_name –

+0

L'avevo visto nel glossario, ma dove è spiegato come definire una funzione setf con (defun (setf foo) ...)? –

2

La risposta di Rainer è azzeccata. Prima di ANSI Common Lisp, era necessario utilizzare defsetf per definire un expander per i luoghi semplici che potevano essere impostati con una semplice chiamata di funzione. Le funzioni setf come (setf arr-index) entrano nella lingua con CLOS e semplificano un sacco di cose. In particolare, le funzioni setf possono essere generiche.