Common lisp push from function -


i have following common lisp functions: (aggregate line1 line2) , (queuer data result).

queuer should push result either values line1 , line2 if have 1st field different, or aggregate of 2 lines if have 1st field equal.

i not know why doesn't change result list.

note: initializing result list (push (pop data) result) have first element there. 2 lists 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        (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)) 

thank insights.

if write functions in lisp preferable think 'functionally'. function takes values , returns values. typical rule avoid side effects. function should return result value, not 'modify' variable value.

instead of:

(defparameter *result* '())  (defun foo (a)    (push *result*)) 

use:

(defparameter *result* '())  (defun foo (a result)   (push result)   result)  (setf *result* (foo *result*)) 

note aggregate not need progn.

slightly advanced (don't that):

if have global list:

(defparameter *foo* '()) 

you can't push onto it, have seen, this:

(defun foo (l)    (push 1 l)) 

if call foo variable *foo* unchanged. reason: lisp not pass variable reference, passes value of variable.

but how can pass reference? well, pass reference: cons cell (or structure, vector, 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) 

now, if @ *foo*, changed. haven't changed variable. have changed first entry of list.

cl-user 42 > *foo* ((1 1)) 

but, don't it. program in functional style.


Comments