Is there any situation where the logic cannot be achieved by foreach, repeat. while etc but can be achieved by mapcar, apply etc.
There is usually more than one way to tackle a problem in AutoLISP, and indeed, every conceivable loop could probably be constructed using only
foreach,
repeat or
while. However, although possible, for some situations this will be far more inefficient and obfuscated than writing an equivalent statement using
mapcar (
apply is not comparable as this function does not iterate over a list).
The first example that springs to mind:
"Write a function that sums the items in two lists and outputs a list of the results."
For example, given two lists:
(1 2 4 6 3 8 7) &
(5 4 7 2 3 1 9), the result should be
(6 6 11 8 6 9 16).
Using
foreach, this might be written as:
_$
(sum
-foreach '
(1 2 4 6 3 8 7) '
(5 4 7 2 3 1 9))(6 6 11 8 6 9 16)
Using
repeat, it might be:
_$
(sum
-repeat '
(1 2 4 6 3 8 7) '
(5 4 7 2 3 1 9))(6 6 11 8 6 9 16)
Using
while, it could be written as:
_$
(sum
-while '
(1 2 4 6 3 8 7) '
(5 4 7 2 3 1 9))(6 6 11 8 6 9 16)
However using
mapcar, this task is a simple one-liner:
_$
(sum
-mapcar '
(1 2 4 6 3 8 7) '
(5 4 7 2 3 1 9))(6 6 11 8 6 9 16)
And the use of the right tool for the job is reflected in the performance:
_$
(setq a '
(1 2 4 6 3 8 7) b '
(5 4 7 2 3 1 9))(5 4 7 2 3 1 9)
224
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):
(SUM
-MAPCAR A B
)......
1451 / 6.56 <fastest
> (SUM
-WHILE A B
).......
7363 / 1.29 (SUM
-REPEAT A B
)......
9516 / 1.00 <slowest
>
And now consider if we want to sum the items in not just
two lists, but
n lists...
Using
mapcar, this is again a simple one-liner:
_$
(sum
-mapcar '
((1 3 4 2) (5 6 2 1) (8 5 1 5) (1 4 5 5)))(15 18 12 13)
But it certainly wouldn't be anywhere near as concise (or efficient) using only
foreach,
while or
repeat.
Restricting yourself to using only
foreach,
while or
repeat for every situation is like trying to build a house with only a hammer - you are depriving yourself of some powerful tools in your AutoLISP toolbox.