Subseq on lists


#1

Hi. Is there any plans on modifying subseq to work on lists (in addition to strings)?

I’ve made such changes to my fork of ulisp-arm (https://github.com/tcoram/ulisp-arm) , but have not taken care to add it in, perhaps, the most exemplary manner. Seems to match Common Lisp’s handling though.


#2

Thanks - it’s a good idea, and I’ll take a look at your code.


#3

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?


#4

Thanks for the feedback. I’ll update my fork with your suggested changes!