功能常见的lisp push [英] Common lisp push from function

查看:91
本文介绍了功能常见的lisp push的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下常见的lisp函数:(aggregate line1 line2)(queuer data result).

I have the following common lisp functions: (aggregate line1 line2) and (queuer data result).

queuer如果第一个字段不同,则应将值line1line2推入结果,如果第一字段相等,则应推入这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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆