[Python-Dev] str() for interpreter output

Ka-Ping Yee ping@lfw.org
Fri, 7 Apr 2000 15:00:09 -0500 (CDT)


Guido van Rossum wrote:
> However, it may be time to switch so that "immediate expression"
> values are printed as str() instead of as repr()...

You do NOT want this.

I'm against this change -- quite strongly, in fact.

Greg Ward wrote:
> Oh, joy! oh happiness! someday soon, I may be able to type
> "blah.__doc__" at the interactive prompt and get a readable result!

Have repr() use triple-quotes when strings contain newlines
if you like, but do *not* hide the fact that the thing being
displayed is a string.

Imagine the confusion this would cause!

(in a hypothetical Python-with-str()...)

    >>> a = 1 + 1
    >>> b = '2'
    >>> c = [1, 2, 3]
    >>> d = '[1, 2, 3]'

...much later...

    >>> a
    2
    >>> b
    2
    >>> a + 5
    7
    >>> b + 5
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
    TypeError: illegal argument type for built-in operation

Huh?!?

    >>> c
    [1, 2, 3]
    >>> d
    [1, 2, 3]
    >>> c.append(4)
    >>> c
    [1, 2, 3, 4]
    >>> d.append(4)
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
    AttributeError: attribute-less object

Huh?!?!

    >>> c[1]
    2
    >>> d[1]
    1

What?!


This is guaranteed to confuse!  Things that look the same should
be the same.  Things that are different should look different.

Getting the representation of objects from the interpreter provides
a very important visual cue: you can usually tell just by looking
at the first character what kind of animal you've got.  A digit means
it's a number; a quote means a string; "[" means a list; "(" means a
tuple; "{" means a dictionary; "<" means an instance or a special
kind of object.  Switching to str() instead of repr() completely
breaks this property so you have no idea what you are getting.
Intuitions go out the window.

Granted, repr() cannot always produce an exact reconstruction of an
object.  repr() is not a serialization mechanism!  We have 'pickle'
for that.  But the nice thing about repr() is that, in general, you
can *tell* whether the representation is accurate enough to re-type:
once you see a "<...>" sort of thing, you know that there is extra
magic that you can't type in.  "<...>" was an excellent choice
because it is very clearly syntactically illegal.

As a corollary, here is an important property of repr() that 
i think ought to be documented and preserved:

    eval(repr(x)) should produce an object with the same value
    and state as x, or it should cause a SyntaxError.

We should avoid ever having it *succeed* and produce the *wrong* x.


                     *        *        *


As Tim suggested, i did go back and read the comp.lang.python
thread on "__str__ vs. __repr__".

Honestly i'm really surprised that such a convoluted hack as the
suggestion to "special-case the snot out of strings" would come
from Tim, and more surprised that it actually got so much airtime.

Doing this special-case mumbo-jumbo would be even worse!  Look:

(in a hypothetical Python-with-snotless-str()...)

    >>> a = '\\'
    >>> b = '\''

...much later...

    >>> a
    '\'
    >>> '\'
      File "<stdin>", line 1
        '\'
          ^
    SyntaxError: invalid token

(at this point i am envisioning the user screaming, "But that's
what YOU said!")

    >>> b
    '''
    >>> '''
    ...

Wha...?!!

Or, alternatively, if even more effort had been expended removing snot:

    >>> b
    "'"
    >>> "'"
    "'"
    >>> print b
    '

Okay... then:

    >>> c = '"\'"
    >>> c
    '"''
    >>> '"''
      File "<stdin>", line 1
        '"''
           ^
    SyntaxError: invalid token

Oh, it should print as '"\'', you say?  Well then what of:

    >>> c
    '"\''
    >>> d = '"\\\''
    '"\\''
    >>> '"\\''
      File "<stdin>", line 1
        '"\\''
             ^
    SyntaxError: invalid token

Damned if you do, damned if you don't.

Tim's snot-removal algorithm forces the user to *infer* the rules
of snot removal, remember them, and tentatively apply them to
everything they see (since they still can't be sure whether snot
has been removed from what they are seeing).

How are the user and the interpreter ever to get along if they
can't talk to each other in the same language?


                     *        *        *


As for the suggestion to add an interpreter hook to __builtins__
such that you can supply your own display routine, i'm all for it.
Great idea there.


                     *        *        *


I think Donn Cave put it best: there are THREE different kinds of
convert-to-string, and we'll only confuse the issue if we try to
ignore the distinctions.

    (a) accurate serialization

    (b) coerce to string

    (c) friendly display

(a) is taken care of by 'pickle'.

(b) is str().  Clearly, coercing a string to a string should not
change anything -- thus str(x) is just x if x is already a string.

(c) is repr().  repr() is for the human, not for the machine.  (a)
is for the machine.  repr() is: "Please show me as much information
as you reasonably can about this object in an accurate and unambiguous
way, but if you can't readably show me everything, make it obvious
that you're not."

repr() must be unambiguous, because the interpreter must help people
learn by example.



-- ?!ng