Danger of the (nth …)
Function
If not used carefully, this function can easily generate
“bad argument” errors in our product. The purpose of this function is to return
the “nth” index entry of a list. The syntax is (nth ix lst) where “ix” the
index (zero-based) and “lst” is a non-nil list.
So, if the “lst” is a four-element list such as (“apple”
3.14 (“banana” “grape”) “CR101”) then the nth function will return the
following:
(nth 0 lst) returns “apple”
(nth 1 lst) returns 3.14
(nth 2 lst) returns (“banana” “grape”) - i.e. a
sublist in the list
(nth 3 lst) returns “CR101”
(nth 4 lst) returns nil
(nth 5 lst) returns nil
…
BUT, if “lst” does not exist (i.e. “lst” is nil), then any
of the above calls will trigger our product to fail with a “bad argument” message in the command window. You
can simulate this by trying it at your command line. Type this (setq xx nil)
[Enter] and then this (nth 0 xx) [Enter].
Under some conditions, the “xx” list above comes through as
undefined or nil. So, when the (nth …) function tries to return the 2nd
element (index = 1) of this non-existent list, our product fails with a “bad
argument” message.
How to use (nth …) Safely
Solution #1 – use (car lst), (cadr lst), (caddr lst) instead
of (nth 0 lst), (nth 1 lst), (nth 2 lst) – these “ca*” functions extract the
same information from the list but do not fail with a “bad argument” message if
the lst does not exist. So, in the above example, (setq typeflag (cadr xx))
would return the same information as (setq typeflag (nth 1 xx)) BUT without the
chance of failing if the list “xx” did not exist. So, (nth 1 xx) fails with
“bad argument” but (cadr xx) returns safely with a returned value of nil.
Solution #2 – add an error check prior to calling the (nth…)
function. In the above example, do something like this: (if xx (setq
typeflag (nth 1 xx))). This expression will only execute the (nth…) function if
“xx” is non-nil. If you really want to make sure that all is well, that xx is
non-nil AND it is a “List”, you could do this: (if (= (type xx)
‘LIST)(setq typeflag (nth 1 xx))). But, in general, the first example is
probably sufficient.