事情就是这样:我没有"获得"setf-expanders,并希望了解它们是如何工作的.
我需要了解它们是如何工作的,因为我遇到了一个问题,这似乎是为什么你应该学习setf-expanders的典型例子,问题如下:
(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)
Run Code Online (Sandbox Code Playgroud)
如何为ARR-INDEX编写合适的setf-expander?
在Practical Common Lisp第17章中.对象重定向:类部分访问器函数,我发现很难理解SETF扩展的方式.
功能:
(defun (setf customer-name) (name account)
(setf (slot-value account 'customer-name) name))
Run Code Online (Sandbox Code Playgroud)
bank-account 类定义:
(defclass bank-account ()
((customer-name
:initarg :customer-name
:initform (error "Must supply a customer name."))
(balance
:initarg :balance
:initform 0)
(account-number
:initform (incf *account-numbers*))
account-type))
Run Code Online (Sandbox Code Playgroud)
我不明白的是:
在表达式(setf (customer-name my-account) "Sally Sue")并(customer-name my-account)返回SETFable槽值customer-name的类的bank-account,然后SETF用来将值设置为"萨利苏"?
(setf (customer-name my-account) "Sally Sue")实际上是在调用上面的函数?
如上定义的是setf customer-name一个函数?
在上面的函数是customer-name在(setf …
我知道当你想在Lisp中创建一个动态/全局绑定时,你可以使用defparameter或defvar.我也知道你可以使用defun参数列表或let语句来制作词法绑定,几乎无处不在.
我想知道的是,当我在这样的语句中声明x未被声明或在代码中的任何其他地方使用时,我究竟是做什么的:
(setf x 10 )
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,x似乎不像一个词法变量.它实际上是一个动态的全局,就像我使用defparameter或defvar一样,还是完全是另一回事?
我正在寻找一种通过将属性值乘以给定因子来修改属性列表中的属性值的方法,类似于使用incf来添加值。
使用incf,我可以说:
(let ((seq '(:x 10 :y 3)))
(incf (getf seq :y) 3)
seq)
-> (:x 10 :y 5)
Run Code Online (Sandbox Code Playgroud)
使用宏,我可以通过以下方式获得结果,但这两次使用了getf:
(defmacro multf (place val)
`(setf ,place (* ,place ,val)))
(let ((seq '(:x 10 :y 3)))
(multf (getf seq :y) 2)
seq)
-> (:x 10 :y 6)
Run Code Online (Sandbox Code Playgroud)
我该怎么做,这样我只能使用getf一次获得相同的结果?
也许有些软件包具有此功能,但是我在网上找不到它。任何帮助表示赞赏!这不是功课,我只是在尝试优化我的代码,并且很好地理解语言。我读了有关setf-expanders和compile-macros的文章,但我不知道它们是否适用于此以及如何使用它们。
我使用setf来显示输出中的小数位.
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
Run Code Online (Sandbox Code Playgroud)
但是,当我将上面的代码放在输出之前时,其他输出也会受到影响.有什么办法我只能用一个输出来设置setf吗?喜欢把它关掉?
非常感谢!
我在Common Lisp(CLISP)中实现了一个进化算法,我遇到了一个问题.
我有一个树状的课:
(defclass node ()
((item :initarg :item :initform nil :accessor item)
(children :initarg :children :initform nil :accessor children)
(number-of-descendants :initarg :descs :initform nil :accessor descs)))
Run Code Online (Sandbox Code Playgroud)
还有一些方法:
(defmethod copy-node ((n node))
(make-instance
'node
:item (item n)
:descs (descs n)
:children (mapcar #'copy-node (children n))))
(defmethod get-subtree ((n node) nr)
(gsth (children n) nr))
(defmethod (setf get-subtree) ((val node) (n node) nr)
(setf (gsth (children n) nr) val))
(defmethod get-random-subtree ((n node))
(gsth (children n) (random (descs n))))
(defmethod (setf …Run Code Online (Sandbox Code Playgroud) 是一种setf能够在同一个地方在CLHS和位置在弱势族群的PAIP?
我试图找出Common Lisp中究竟是什么地方,但对我来说是HyperSpec的解释
地方 1.一种适合用作一般参考的表格.2.这样一个地方提到的概念位置[1].
只是有限的帮助.
(我知道这不是那种适合SO的问题,但如果有人知道一篇解释setfable/place/location的好文章,我会很感激链接/参考)
目前正在学习常见的口齿不清,继Peter Seibel的Practical Common Lisp(我在第11章,关于收藏)之后,我很难理解setf幕后的工作方式.
考虑这个表达式:
(setf a 10)
Run Code Online (Sandbox Code Playgroud)
我完全理解解释器如何(1)检索名为的变量a,以及(2)更改它指向的值10.
现在,我是特定集合的例子,例如列表,向量或散列表,setf也可用于更改集合包含的值.例如,使用向量:
(defparameter *x* '(a b c d))
(setf (elt *x* 1) bb)
Run Code Online (Sandbox Code Playgroud)
这让我怀疑setf,因为它最终会找到非平凡的信息,或制造黑魔法.我看到了多种可能性.
该(elt *x* 1)表达式返回'b,因此setf实际上被有工作(setf b bb).然后我不明白如何setf推断*x*它必须修改哪个对象(这里是列表),而不具有elt保持它来自集合的指示的返回值,以及指向所述集合的指针.看似复杂.
这个想法就像setf宏一样,它直接与它一起工作(setf (elt *x* 1) bb),因此可以提取elt *x* 1部件来推断使用哪个对象/集合,因此必须进行修改.
它似乎不是非常有效,也不可靠,也不能抵抗复杂的操作.但是,因为我无法运行此代码:
(funcall (find-symbol (concatenate 'string "E" "LT")) *x* 1) ; -> B …Run Code Online (Sandbox Code Playgroud) 我知道我可以在Common Lisp中执行以下操作:
CL-USER> (let ((my-list nil))
(dotimes (i 5)
(setf my-list (cons i my-list)))
my-list)
(4 3 2 1 0)
Run Code Online (Sandbox Code Playgroud)
我怎么在Clojure中这样做?特别是,如果没有Clojure中的setf,我该怎么做呢?
使用Common Lisp进行开发时,我们有三种定义新setf形式的可能性:
我们可以定义一个函数,其名称是两个符号的列表,第一个是setf例如(defun (setf some-observable) (…)).
我们可以使用简短形式defsetf.
我们可以使用长形式defsetf.
我们可以用define-setf-expander.
我不确定每种可能性的正确或预期用例是什么.
对这个问题的回答可能会暗示最通用的解决方案和概述其他解决方案优越的背景.