功能常见的lisp push [英] Common lisp push from function
问题描述
我具有以下常见的lisp函数:(aggregate line1 line2)
和(queuer data result)
.
I have the following common lisp functions: (aggregate line1 line2)
and (queuer data result)
.
queuer
如果第一个字段不同,则应将值line1
和line2
推入结果,如果第一字段相等,则应推入这2行的合计.
queuer
should push into result either the values line1
and line2
if they have the 1st field different, or the aggregate of those 2 lines if they have the 1st field equal.
我不知道为什么它不会改变我的结果列表.
I do not know why it doesn't change my result list.
注意:我正在用(push (pop data) result)
初始化结果列表,以使第一个元素在那里.这2个列表是1深度嵌套列表(("1" "text") ("2" "text") (...))
.
Note: I am initializing the result list with a (push (pop data) result)
to have the first element there. The 2 lists are 1-depth nested lists (("1" "text") ("2" "text") (...))
.
(defun aggregate (line1 line2)
(progn
(list
(nth 0 line1)
(nth 1 line1)
(nth 2 line1)
(concatenate 'string (nth 3 line1) ", " (nth 3 line2))
(concatenate 'string (nth 4 line1) ", " (nth 4 line2)))))
(push (pop x) y)
(defun queuer (data result)
(loop do
(let ((line1 (pop data))
(line2 (pop result)))
(if (equal (first line1) (first line2))
(progn
(push (aggregate line1 line2) result)
(print "=="))
(progn
(push line2 result)
(push line1 result)
(print "<>"))))
while data))
谢谢您的见解.
推荐答案
如果用Lisp编写函数,最好考虑功能性".函数获取值并返回值.一个典型的规则是避免副作用.因此,您的函数应该返回结果值,而不是修改"变量值.
If you write functions in Lisp it is preferable to think 'functionally'. A function takes values and returns values. A typical rule would be to avoid side effects. So your function should return a result value, not 'modify' a variable value.
代替:
(defparameter *result* '())
(defun foo (a)
(push a *result*))
使用:
(defparameter *result* '())
(defun foo (a result)
(push a result)
result)
(setf *result* (foo a *result*))
还请注意,aggregate
不需要progn
.
稍微高级(不要这样做):
如果您有全局列表:
(defparameter *foo* '())
就像我们已经看到的那样,您不能像这样:
You can't push onto it, as we have seen, like this:
(defun foo (l)
(push 1 l))
如果调用foo
,则变量*foo*
不变.原因:Lisp没有传递变量引用,而是传递了变量的值.
If you call foo
the variable *foo*
is unchanged. Reason: Lisp does not pass a variable reference, it passes the value of the variable.
但是如何传递参考?好吧,传递一个引用:一个cons单元可以做到这一点(或一个结构,一个向量,一个CLOS对象……):
But how can we pass a reference? Well, pass a reference: a cons cell would do it (or a structure, a vector, a CLOS object, ...):
CL-USER 38 > (defparameter *foo* (list '()))
*FOO*
CL-USER 39 > (defun foo (ref)
(push 1 (first ref)))
FOO
CL-USER 40 > (foo *foo*)
(1)
CL-USER 41 > (foo *foo*)
(1 1)
现在,如果我们查看*foo*
,它将被更改.但是我们并没有真正更改变量.我们已经更改了列表的第一项.
Now, if we look at *foo*
, it is changed. But we haven't really changed the variable. We have changed the first entry of the list.
CL-USER 42 > *foo*
((1 1))
但是,不要这样做.以功能性风格进行编程.
But, don't do it. Program in a functional style.
这篇关于功能常见的lisp push的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!