Re: Can't take the tail of a list without copying via List[1:]?

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Wed, 10 Aug 1994 16:16:56 -0400

On Aug 8, 15:46, Aaron Watters wrote:
>
> Now, the following cannot be done using built-in python lists:
> (setq x ("This" 'dummy))
> (setf (rest x) x)
> which creates the cyclic list x=("This" "This" "This" "This" ...)

Just try:
>>> x = [ "This", None ]
>>> x[1] = x
>>> x
>>> ['This', ['This', ['This', ['This', ['This', ['This' ...

And recall that the typical Lisp representation of a List:
( A B C D E )
is really just shorthand and prettyprinting of:
( A . ( B . ( C . ( D . ( E . Nil )))))

That is, Lisp lists are recursive pairs.
You can use either python tuples or lists ( which can store pairs,
singletons, or any number of items ) to make a structure very like
Lisp lists. [ If you want to be able to modify the elements in
place ala replcar/replacdr, then use Python lists rather than
Python tuples for the pair structure.

You can also represent pairs with a Python class:

class Cons: pass

x = Cons()
x.car = 'This'
x.cdr = x

> You also cannot create lists that share, for example, a common
> tail (without copying the tail):
> (setq tail (2 4))
> (setq mults-of-2 `(0 . ,tail))
> (setq powers-of-2 `(1 , ,tail))
>

All of those possible implementations can share common sub-sequences,
but if you want them to print and act like lisp Lists, then you
DO have to define a class that implements car, cdr, and __repr__()
in a lisp-like fashion. Call the class Cons and make the __init__
function expect a pair of values and you have your constructor.
( __repr__ is the only non-trivial method. )

However, if you want all of the Python sequence operations
like for, map, filter, reduce, etc. to also work on these Lisp-like
"dotted pair" lists, you also have to redefine __getitem__ to flatten
the list. i.e. values returned for index elements [0], [1], [2], [3], ...
are actually the car, cadr, caddr, cadddr, ..., or if actually
represented by a Python list: [0], [1][0], [1][1][0], [1][1][1][0], ...

[ I believe there was an interesting past discussion of references
and object sharing in the archive somewhere. If I can find it, I'll
post the highlights. ]

- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU>
- UVA Department of Molecular Physiology and Biological Physics