2012-07-12 15 views
11

Hier ist die Sache: Ich bekomme keine SETF-Expander und möchte lernen, wie sie funktionieren.Definieren von Setf-Expandern in Common Lisp

ich lernen müssen, wie sie arbeiten, weil ich ein Problem habe, das für Sie, setf-Expander wie ein typisches Beispiel scheint, ist das Problem wie folgt sollten lernen:

(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) 

Wie kann ich schreiben ein richtiger Setf-Expander für ARR-INDEX?

Antwort

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

In Common Lisp eine function name kann nicht nur ein Symbol, sondern auch eine Liste von zwei Symbolen mit SETF als das erste Symbol. Siehe oben. DEFUN kann somit SETF Funktionen definieren. Der Name der Funktion lautet (setf arr-index).

A setf Funktion kann in einer Ort Form verwendet werden: CLHS: Other compound forms as places.

Der neue Wert ist dann das erste Argument.

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

Ich konnte das nicht in der CLHS finden, wo ist es? –

+0

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

+0

Ich hatte es im Glossar gesehen, aber wo wird erklärt, wie man eine setf Funktion mit (defun (setf foo) ...)? –

2

Rainers Antwort ist genau richtig. Vor ANSI Common Lisp war es notwendig, defsetf zu verwenden, um einen Expander für einfache Stellen zu definieren, die mit einem einfachen Funktionsaufruf gesetzt werden konnten. setf Funktionen wie (setf arr-index) kamen in die Sprache mit CLOS und vereinfachen eine Menge Dinge. Insbesondere können setf Funktionen generisch sein.