2012-07-12 48 views
11

Đây là điều: Tôi không "có được" setf-expanders và muốn tìm hiểu cách chúng hoạt động.định nghĩa setf-expanders trong Common Lisp

tôi cần phải học cách họ làm việc vì tôi đã có một vấn đề mà có vẻ giống như một ví dụ điển hình cho lý do tại sao bạn nên tìm hiểu setf-expanders, vấn đề là như sau:

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

Làm thế nào để viết một bộ mở rộng thích hợp cho ARR-INDEX?

Trả lời

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

Trong Common Lisp một function name có thể không chỉ là một biểu tượng, mà còn là một danh sách các biểu tượng với hai SETF như biểu tượng đầu tiên. Xem ở trên. DEFUN do đó có thể xác định các hàm SETF. Tên của hàm là (setf arr-index).

Một setf chức năng có thể được sử dụng trong một nơi hình thức: CLHS: Other compound forms as places.

Giá trị mới là đối số đầu tiên sau đó.

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

Tôi không thể tìm thấy điều này trong CLHS, ở đâu? –

+0

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

+0

Tôi đã thấy nó trong bảng chú giải thuật ngữ, nhưng nó giải thích cách xác định hàm setf bằng (defun (setf) foo) ...)? –

2

Câu trả lời của người dùng đang bật. Trước ANSI Common Lisp, cần phải sử dụng defsetf để xác định một expander cho những nơi đơn giản có thể được thiết lập với một cuộc gọi hàm đơn giản. Các hàm setf như (setf arr-index) được đưa vào ngôn ngữ bằng CLOS và đơn giản hóa rất nhiều thứ. Đặc biệt, các chức năng setf có thể là chung chung.