loopsfunctional-programminglispcommon-lispclisp

re-write without using set, setf or setq


I need some help to re-write this function in common lisp without usin SET, SETF or SETQ (I can't also use loops), I hope some one can help me. here is the code:

(defun apply-values (DictValues Monomial)
   (let ( (Coeff (monomial-coefficient Monomial))
          (Vars (varpowers Monomial))
          (Acc 1) )
     (mapcar (lambda(x)
               (setf Acc 
                 (* Acc (expt (cdr (assoc (varpower-symbol x) 
                                          DictValues))
                              (varpower-power x))))) 
             Vars)
     (* Coeff Acc)))

my problem is at the line that starts with mapcar.

thanks in advance for your help!


Solution

  • Repeated accumulative operation over a list is known as reduction:

    (defun apply-values (DictValues Monomial)
       (reduce #'*
          (mapcar 
             (lambda (x)
                (expt (cdr (assoc (varpower-symbol x) DictValues))
                      (varpower-power x)))
             (varpowers Monomial))
          :initial-value (monomial-coefficient Monomial)))
        
    

    Using a higher-order function that properly fits the situation allows for the functional style, without explicitly naming the interim values. The code is clearer and less prone to errors by a human coder.