"self" in a class is annoying and errorprone

Kaz Kylheku kaz at ashi.footprints.net
Thu Feb 13 03:04:28 CET 2003


Meinrad Recheis <meinrad.recheis at aon.at> wrote in message news:<3E4A2237.4080800 at aon.at>...
> hello everyone,
> 
> I think it must be possible to change python so that self can be omitted 
> inside a class
> 	# except for some reasons like this:
> 	__init__(""" i dont like this self """ self, x)
> 		self.x = x    # here self is useful
> 	
> 
> self is simply annoying.
> (why allways need self as first parameter?? the interpreter could mask 
> that for us)
> self is prone to be forgotten!!

Your analysis is extremely shortsighted. It's the hidden self (or
``this'', by another name) that is dangerous and stupid. Consider this
C++ snippet:

  int x;

  foo::bar()
  {
     x = y;
  }

what are x and y? Are they members of class foo? Or global variables?

Suppose that x is initially the global variable, but then later a
member is introduced to the class declaration. The meaning of x = y
suddenly changes elsewhere in the program! It's no longer an
assignment to the global, but to the member variable.

The workaround that many C++ programmers use is to apply some common
lexical feature to member names, like ``m_'' and the like. What is
that, if not a re-introduction of the explicit ``self.'', in a
two-character version?

Another workaround is to always use :: when referring to globals.

> leads to potential scope errors

See above!

> would make source code shorter, and more beautiful

Design decisions in programming language can't be made based on such
ill-conceived, subjective considerations. Brevity is a false god, and
beauty is in the eye of the beholder. Those who argue based on beauty
always pick some trivial textbook examples, rather than huge, complex
programs that have been maintained for years.
 
Ideally, any name uttered in a program should be understood purely in
terms of lexical scope; and failing that, it should be understood to
be in some global environment.

That is, seeing the identifier X being evaluated in the program, you
should be able to examine the nesting scopes, starting inside and
going out, until you discover a construct which establishes the
binding for X, making it clear what it refers to. If you don't find
such a binding, then you know X is somewhere in the global
environment, or else it is undefined.

> shouldn t that be discussed for the sake of PYTHON?

No.

If you want short names to refer to members, introduce a binding
construct, like WITH-SLOTS in Lisp. Have it support optional renaming:

  (defmethod draw-line ((p0 point) (p1 point))
    (with-slots ((x0 x) (y0 y)) p0
      (with-slots ((x1 x) (y1 y)) p1
        (graphics-lib::line x0 y0 x1 y1))))

There is no ambiguity here about what anything means. The meaning of
x0 in the innermost expression is readily traced to a lexically
enclosing WITH-SLOTS binding construct. Moreover, the appearance of
the symbol X in that construct takes place in a context which is clear
from the semantics of the construct: it denotes a slot called X in the
object P0. If P0 has no such slot, then the construct is in error.

There is beauty in being able to understand some text without
requiring lots of other context pulled from distant places.




More information about the Python-list mailing list