i want to write a function that accepts 2 lists as argument and return multiplication of them in a list. like this:
(3 4) (3 5 6) => (9 15 18 12 20 24)
this is the code that i've came up with but i receive an error which is telling me that i have too few arguments for map.
(defun multip (lst lst2)
;this is a function to flatten the result
(defun flatten (tree)
(let ((result '()))
(labels ((scan (item)
(if (listp item)
(map nil #'scan item)
(push item result))))
(scan tree))
(nreverse result)))
(flatten (map (lambda (i) (map (lambda (j) (* i j)) lst )) lst2))
)
(write (multip '(3 4 6) '(3 2) ))
i can not understand what am i doing wrong. i appreciate your comment.
You should use mapcar
instead of map
:
(mapcar (lambda (i) (mapcar (lambda (j) (* i j)) lst )) lst2))
These are two different functions: mapcar
maps a function on one or more lists, and requires at least two arguments, while map
is the equivalent but for any kind of sequences (e.g. vectors), and requires an additional argument specifying the type of the result. See the reference for map
here, and the reference for mapcar
here.
Style
You are using a defun
inside another defun
: this is not good style, since every time multip
is called it redefines globally the function flatten
. You should either define flatten
externally, only once, or use a local declaration of function with flet
or labels
(as for the internal function scan
inside flatten
.)
For alternative and more simple definitions of flatten
, you can see this question in SO.