Question

I have a function that takes 2 lists as input and I would like to make it so that everything in the first list, is multiplied with everything in the second list, and then the sum is calculated.

Here's my function so far:

(defun multiply(a b)
(if (eq a nil)
0
(progn
      (* (car a) (car b))
  (multiply (car a) (cdr b)))
))

Currently all I'm trying to get it to do is take the first number from the first list, and multiply one by with everything in the second list. However I get this error from when the function is re-called within the function:

(This is what I inputted, '(1 2 3) and '(4 5 6))

The value 1 is not of type list.

(MULTIPLY 1 '(5 6))

Any help would be much appreciated.

Was it helpful?

Solution

Is loop acceptable?

Case 1

If the result should be 90 as in

(+ (* 1 4) (* 1 5) (* 1 6) (* 2 4) (* 2 5) (* 2 6) (* 3 4) (* 3 5) (* 3 6))

then you could do

(defun multiply (a b)
  (loop for i in a
    sum (loop for j in b
          sum (* i j))))

Case 2

If the result is supposed to be 32 as in

(+ (* 1 4) (* 2 5) (* 3 6))

then it would be

(defun multiply (a b)
  (loop 
    for i in a
    for j in b
    sum (* i j)))

OTHER TIPS

If you want to multiply two lists per element, you should just be able to use mapcar:

(mapcar #'* '(3 4 5) '(4 5 6))

As to the error in your existing function, this line should be:

...
  (multiply (cdr a) (cdr b)))
...

What you describe sounds like the dot product:

(defun dot (l1 l2)
  (reduce #'+ (mapcar #'* l1 l2)))

The above solution is nice because it is purely functional, but, alas, it creates an unnecessary intermediate list. Of course, a Sufficiently Smart Compiler should be able to eliminate that, but, practically speaking, you are better off using loop:

(defun dot (l1 l2)
  (loop for x in l1 and y in l2 sum (* x y)))

Note also that using lists to represent mathematical vectors is not a very good idea, use vectors instead.

I would modify multiply as

(defun multiply(a b)
  (if (eq a nil)
      0
    (+
      (* (car a) (car b))
      (multiply (cdr a) (cdr b)))))

When you call

(multiply '(1 2 3) '(4 5 6))

it will return the sum

32
(define (*2Ls L1 L2)
    (apply map * (list L1 L2)))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top