Your code looks good! Just one little quirk:
If the third parameter to subseq is omitted you set end to the length of the list by calling listlength(), which correctly objects if the list is not a proper list:
> (subseq '(a b c d . e) 1)
Error: 'length' argument is not a proper list
(Note: you should probably change listlength(LENGTH, arg)
to listlength(SUBSEQ, arg
) to make the error message correct).
You also check for a proper list when setting start, which catches this situation:
> (subseq '(a b c d . e) 4 5)
Error: 'subseq' argument is not a proper list: e
However, the following case doesn’t detect if the list isn’t a proper list:
> (subseq '(a b c d . e) 1 5)
(b c d . nil)
I think you could solve this with another statement like:
if (improperp(list)) error(SUBSEQ, notproper, list);
in the second while loop.
By the way, LispWorks Common Lisp avoids all these problems by giving an error whenever the first argument to subseq isn’t a proper list, but I don’t see why this is necessary. I’ve written about this before; see:
Why can’t subseq cope with a dotted list?