この質問は、Common Lispsetf
マクロと、その引数フォーム (およびサブフォーム) を評価する方法に関するものです。(これは、 get-setf-expansion の使用のコメントにある例の一部をフォローアップしたものでもあります。)
;create a list of two hash tables
* (defparameter hts (list (make-hash-table) (make-hash-table)))
HTS
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>)
;define a function that swaps the position of the two hash tables
* (defun next-ht (hts)
(rotatef (first hts) (second hts))
(second hts))
NEXT-HT
スワッピング:
;now do a swap to verify it works
* (next-ht hts)
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>)
;and swap them back
* (next-ht hts)
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>
* hts
(#<HASH-TABLE :TEST EQL :COUNT 0 {1007F76CB3}>
#<HASH-TABLE :TEST EQL :COUNT 0 {1007F77103}>)
さらなるテスト:
;then set different values for a key in each table
* (setf (gethash 0 (first hts)) 11)
11
* (setf (gethash 0 (second hts)) 22)
22
* hts
(#<HASH-TABLE :TEST EQL :COUNT 1 {1007F76CB3}>
#<HASH-TABLE :TEST EQL :COUNT 1 {1007F77103}>)
;finally execute a setf with a swapping side-effect
* (setf (gethash 0 (next-ht hts)) (1+ (gethash 0 (next-ht hts))))
23
;but it looks like hts has been swapped twice
;back to its original state
* hts
(#<HASH-TABLE :TEST EQL :COUNT 1 {1007F76CB3}>
#<HASH-TABLE :TEST EQL :COUNT 1 {1007F77103}>)
;also, where did the initial value of 11 go?
* (gethash 0 (first hts))
23
T
* (gethash 0 (second hts))
22
T
*
誰かが何が起こっているのかを明確にすることができますか? setf
また、副作用のある式の意味は何ですか?