E.g.:
;; Adding 2 lists together
numbers1 '(1 2 3 4)
numbers2 '(5 6 7
(setq total
(+ (nth index numbers1
) (nth index numbers2
)))) answer ;Return (6 8 10 12)
;; In this case mapcar works a lot simpler
(setq numbers1 '
(1 2 3 4) numbers2 '(5 6 7)
(mapcar '
+ numbers1 numbers2
) ;Returns (6 8 10 12)
Doing the same with foreach makes for a lot more coding (actually it's nearly impossible to add 2 lists together by only using foreach), since foreach only works from one single list (not 2 or more like mapcar). And it only returns the last calculation's result, so you'd need a temporary variable like the answer in the while loop. But also as dgorsman's indicated foreach starts at the begining of the list - so you might have to reverse the answer at the end.
E.g. here's a scenario where mapcar and foreach can equally be applied. Say you want to square each item in the list:
(defun sqr
(num
) (* num num
))
;; Standard while loop
numbers '(1 2 3 4)
answer ;Returns (1 4 9 16)
;; Using foreach instead
numbers '(1 2 3 4))
(reverse answer
) ;Since answer is built back-to-front using cons, the reverse returns (1 4 9 16)
;; But see how much simpler mapcar is
(setq numbers '
(1 2 3 4)) (mapcar 'sqr numbers
) ;Returns (1 4 9 16)
There's another possibility (we'd need some more info as to what the OP is after), apply can also be used on a list. If there's only one list, then foreach could also be used. E.g. summing the values of a list together:
;; Instead of this
numbers '(1 2 3 4)
(setq total
(+ total
(nth index numbers
)))) total ;Return 10
;;You could use this
numbers '(1 2 3 4))
(setq total
(+ total num
))) numbers) ;This actually returns (1 3 6 10)
total ;Return 10
;; But probably this seems more conducive to this scenario
numbers '(1 2 3 4))
(setq total
(+ total num
))) total ;Return 10
But if the function you want to apply onto all the items in the list can accept more than one argument, you can use apply
;; The total can be done like this of course
(+ 1 2 3 4)
;; But consider you don't know the list of arguments' contents and/or length at the time you write your code
(setq numbers '
(1 2 3 4))
The apply works as if you send the 2nd argument (the list) as parameters of the 1st argument (the function).
So the 3 alternatives each have their own scenarios where they become handy. Unfortunately AutoLisp does not have the &rest modifier for arguments - otherwise you could have made your own defun to use with the apply function. So unlike in Common Lisp the apply is less useful than it may have been - if the function is more involved than one of the built-in multi-argument functions, then you're probably better off using a foreach.
I've also tried to show you variations where either (or even any of the 3) can be used to get the exact same result. When such happens then it's up to you which you prefer using. It's a bit subjective, since the one might be more readable to you - while to others they might feel it's more succinct to go a different route. There's no one single answer which covers all possibilities, e.g. with squaring it seemed as if mapcar is nicer to use, but for total the foreach was less convoluted than mapcar (ignoring apply in this scenario to make a point
).
One thing I can say, mapcar calls a function (which has a small effect on performance - especially with lambda functions), foreach inlines the code which usually then executes faster. Also compiling your lisp to FAS/VLX tends to optimize foreach a bit better than mapcar, this can be alleviated by setting lambda's to be seen as normal functions (see the function keyword). Though if apply can be used, I'd say rather go with it - it's usually much faster than either foreach/mapcar - compiled or not; and IMO it's more readable; and definitely more succinct (read less typing + less chance for typos).