Pymacs - tuples/lists .vs. proper-lists/vectors

François Pinard pinard at
Mon Sep 17 16:14:15 CEST 2001

[Brian McErlean]

> While there are patterns I use in python with lists that rely on extending, 
> eg. building lists like:

> l=[]
> while cond:
> 	<do stuff to get next element>
> 	l.append(next_element)

> I wouldn't use a similar pattern in lisp with either lists or tuples,
> so I don't think this is an issue.

Very, very often, people write things like:

   (setq accumulator (cons 'new-item accumulator))

or more simply:

   (push accumulator new-item)

That is, proper lists are good for appending stuff, yet in LISP, we "append
at the beginning" for speed.  So, proper lists in LISP and lists in Python
are the normal things for which length is easily modified.  Some .reverse()
or (nreverse ...) operation might be needed on either side in case speed
is especially important and many modifications happen in a row on the same
side, while order of elements ought to be preserved.

We cannot so easily change the size of a vector, the same as it requires
a bit more stunts to "modify" a tuple.  The shape of these objects is fixed.

> Don't underestimate the benefit of similar syntax too.  I think it is
> a useful reminder.

Yes.  This has been one point in my reluctance to the change.  Now that it
is done, I think it will not be difficult (for me at least) to get used
to the equivalence.

Note that in Python, both tuples and lists have O(1) access.  So, there
is no real speed consideration there.  LISP is different: vectors have
O(1) access while lists have O(N) access.  But the rigidity of LISP
vectors is such that people do not resort to vectors unless there is a
speed issue, so in real LISP practice, vectors are used parsimoniously.
So parsimoniously, in fact, that LISP vectors are overloaded for what
they are not meant: for example, very small vectors are used to represent
X events in key-maps, programmers only want to test for the vector type,
and users like bracketed syntax.  Speed of access is hardly an issue.

Whenever, under the new Pymacs scheme, a LISP vector is needed,
one has to write `tuple(python_list)' while transmitting the object.
Such transmissions are most probably to be unusual, as people are not going
to blindly transmit whole big structures back and forth between Emacs and
Python, they would rather do it once in a while only, and do only local
modifications afterwards.

Since LISP proper lists and Python lists are the bread-an-butter of
algorithms modifying structures, at least in my experience, I guess they
are more naturally mapped into one another, this will spare many casts.

Mapping vectors to tuples, which is admittedly strange, will only be done if
the Python side requests an expanded copy, otherwise an opaque LISP object
is seen in Python.  While in the other direction, the infrequent casting to
`tuple' for getting a LISP vector seems to be a reasonable compromise.

François Pinard

More information about the Python-list mailing list