Method default argument whose type is the class not yet defined

Oscar Benjamin oscar.j.benjamin at
Mon Nov 12 01:31:53 CET 2012

On 11 November 2012 22:31, Steven D'Aprano
<steve+comp.lang.python at> wrote:
> On Sun, 11 Nov 2012 14:21:19 +0000, Oscar Benjamin wrote:
>> On 11 November 2012 02:47, Chris Angelico <rosuav at> wrote:
>>> On Sun, Nov 11, 2012 at 1:43 PM, Ian Kelly <ian.g.kelly at>
>>> wrote:
>>>> On Sat, Nov 10, 2012 at 7:13 PM, Chris Angelico <rosuav at>
>>>> wrote:
>>>>> I would not assume that. The origin is a point, just like any other.
>>>>> With a Line class, you could deem a zero-length line to be like a
>>>>> zero-element list, but Point(0,0) is more like the tuple (0,0) which
>>>>> is definitely True.
>>>> It's more like the number 0 than the tuple (0,0).
>>>> 0 is the origin on a 1-dimensional number line. (0,0) is the origin on
>>>> a 2-dimensional number plane.
>>>> In fact, it might be pointed out that Point(0, 0) is a generalization
>>>> of 0+0j, which is equal to 0.
>>> Ah, good point. In any case, though, it'd be an utterly inconsequential
>>> bug.
>> You were right the first time, Chris. A point that happens to coincide
>> with the arbitrarily chosen origin is no more truthy or falsey than any
>> other. A vector of length 0 on the other hand is a very different beast.
> Nonsense. The length and direction of a vector is relative to the origin.
> If the origin is arbitrary, as you claim, then so is the length of the
> vector.

Wrong on all counts. Neither the length not the direction os a vector
are relative to any origin. When we choose to express a vector in
Cartesian components our representation assumes an orientation for the
axes of the coordinate system. Even in this sense, though, the origin
itself does not affect the components of the vector.

I have spent a fair few hours in the past few weeks persuading
teenaged Engineering students to maintain a clear distinction between
points, vectors and lines. One of the ways that I distinguish vectors
from points is to say that a vector is like an arrow but its base has
no particular position. A point on the other hand is quite simply a
position. Given an origin (an arbitrarily chosen point) we can specify
another point using a "position vector": a vector from the origin to
the point in question.

> Just because we can perform vector transformations on the plane to move
> the origin to some point other that (0,0) doesn't make (0,0) an
> "arbitrarily chosen origin". It is no more arbitrary than 0 as the origin
> of the real number line.

(0, 0) are the coordinates of the origin *relative to itself*. Had we
chosen a different origin, the point that was previously called (0, 0)
would now be called (a, b) for some other numbers a and b.

> And yes, we can perform 1D vector transformations on the real number line
> too. Here's a version of range that sets the origin to 42, not 0:
> def myrange(start, end=None, step=1):
>     if end is None:
>         start = 42
>     return range(start, end, step)

This is lost on me...

> Nevertheless, there really is something special about the point 0 on the
> real number line


> , the point (0,0) on the complex number plane,

Also agreed.

> the point
> (0,0,0) in the 3D space, (0,0,0,0) in 4D space, etc. It is not just an
> arbitrary convention that we set the origin to 0.

Wrong. The point (0,0,0,...) in some ND space is an arbitrarily chosen
position. By this I don't mean to say that the sequence of coordinates
consisting of all zeros is arbitrary. The choice of the point *in the
real/hypothetical space* that is designated by the sequence of zero
coordinates is arbitrary.

> In other words: to the extent that your arguments that zero-vectors are
> special are correct, the same applies to zero-points, since vectors are
> defined as a magnitude and direction *from the origin*.

Plain wrong. Vectors are not defined *from any origin*.

> To put it yet another way:
> The complex number a+bj is equivalent to the 2D point (a, b) which is
> equivalent to the 2D vector [a, b]. If (0, 0) shouldn't be considered
> falsey, neither should [0, 0].

a+bj is not equivalent to the 2D point (a, b). It is possible to
define a mapping between complex numbers and a 2D space so that a+bj
corresponds to the point (a, b) *under that map*. However there are an
infinite number of such possible mappings between the two spaces
including a+bj -> (a+1, b+1).

>> The significance of zero in real algebra is not that it is the origin
>> but rather that it is the additive and multiplicative zero:
>>    a + 0 = a  for any real number a
>>    a * 0 = 0 for any real number a
> I'm not sure what you mean by "additive and multiplicative zero", you
> appear to be conflating two different properties here. 0 is the additive
> *identity*, but 1 is the multiplicative identity:

I mean that it has the properties that zero has when used in addition
and multiplication:

> a + 0 = a
> a * 1 = a
> for any real number a.

No. I meant the two properties that I listed.

> If the RHS must be zero, then there is a unique multiplicative zero, but
> no unique additive zero:
> a * 0 = 0 for any real number a
> a + -a = 0 for any real number a

That is not the same as:

a + 0 = a

>> The same is true for a vector v0, of length 0:
>>    v + v0 = v for any vector v
>>    a * v0 = v0 for any scalar a
> Well that's a bogus analogy. Since you're talking about the domain of
> vectors, the relevant identify for the second line should be:
> v * v0 = v0 for any vector v
> except that doesn't work, since vector algebra doesn't define a vector
> multiplication operator.[1] It does define multiplication between a
> vector and a scalar, which represents a scale transformation.

That is precisely the multiplication operation that I was referring
to. There are other senses of vector multiplication between vectors
for which v0 will also behave as a "zero" under multiplication:

v . v0 = 0 for any vector v
v x v0 = 0 for any vector v

>> There is however no meaningful sense in which points (as opposed to
>> vectors) can be added to each other or multiplied by anything, so there
>> is no zero point.
> I think that the great mathematician Carl Gauss would have something to
> say about that.

Is the text below a quote?

> Points in the plane are equivalent to complex numbers, and you can
> certainly add and multiply complex numbers. Adding two points is
> equivalent to a translation; multiplication of a scalar with a point is
> equivalent to a scale transformation. Multiplying two points is
> equivalent to complex multiplication, which is a scale + a rotation.

The last point is bizarre. Complex multiplication makes no sense when
you're trying to think about vectors. Draw a 2D plot and convince
yourself that the square of the point (0, 1) is (-1, 0).

> Oh look, that's exactly the same geometric interpretation as for vectors.
> Hardly surprising, since vectors are the magnitude and direction of a
> line from the origin to a point.

Here it becomes clear that you have conflated "position vectors" with
vectors in general. Let me list some other examples of vectors that
are clearly not "from the origin to a point":

electric field
angular momentum
wave vector

(I could go on)

>> The relationship between points and vectors is analogous to the
>> relationship between datetimes and timedeltas. Having Vector(0, 0)
>> evaluate to False is analogous to having timedelta(0) evaluate to False
>> and is entirely sensible. Having Point(0, 0) evaluate to False is
>> precisely the same conceptual folly that sees midnight evaluate as
>> False.
> If you are dealing with datetimes, then "midnight 2012-11-12" is not
> falsey. The only falsey datetime is the zero datetime. Since it would be
> awfully inconvenient to start counting times from the Big Bang, we pick
> an arbitrary zero point, the Epoch, which in Unix systems is midnight 1
> January 1970, and according to the logic of Unix system administrators,
> that is so far in the distant past that it might as well be the Big Bang.
> (People with more demanding requirements don't use Unix or Windows
> timestamps for recording date times. E.g. astronomers use the Julian
> system, not to be confused with the Julian calendar.)
> The midnight problem only occurs when you deal with *times* on their own,
> not datetimes, in which case the relationship with timedeltas is not
> defined. How far apart is 1:00am and 2:00am? Well, it depends, doesn't
> it? It could be 1 hour, 25 hours, 49 hours, ...
> In any case, since times are modulo 24 hours, they aren't really relevant
> to what we are discussing.

They are relevant. The point is that conflating points and vectors is
the same as conflating datetime and timedelta objects. The zero of
datetime.timedelta objects is not arbitrary but the zero of
datetime.time objects is.

> Since vectors are equivalent to points, and points are equivalent to
> complex numbers, one could define a vector operation equivalent to
> complex multiplication. There is a natural geometric interpretation of
> this multiplication: it is a scaling + rotation.

Vectors, points and complex numbers are not equivalent. There are
cases in which it is reasonable to think of them as equivalent for a
particular purpose. That does not diminish the fundamental differences
between them.


More information about the Python-list mailing list