repr and srepr

132 views
Skip to first unread message

krastano...@gmail.com

unread,
May 27, 2011, 2:33:26 PM5/27/11
to sy...@googlegroups.com
I know (or I think I know) that eval(srepr(thing)) == thing in sympy.

Should this be also true for repr (the python build-in)? Why are there two different functions that should be doing the same thing? Is repr hard do modify?

Regards
Stefan

Mateusz Paprocki

unread,
May 27, 2011, 2:39:39 PM5/27/11
to sy...@googlegroups.com
Hi,

On 27 May 2011 20:33, krastano...@gmail.com <krastano...@gmail.com> wrote:
I know (or I think I know) that eval(srepr(thing)) == thing in sympy.

Yes, that should hold (otherwise it's a bug).
 

Should this be also true for repr (the python build-in)? Why are there two different functions that should be doing the same thing? Is repr hard do modify?

In SymPy repr() == str() == sstr(). This has to work like this due to a bug in Python (see issue 2388 for more details).
 

Regards
Stefan

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to sympy+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sympy?hl=en.

Mateusz

Ronan Lamy

unread,
May 27, 2011, 3:53:48 PM5/27/11
to sy...@googlegroups.com
Le vendredi 27 mai 2011 à 20:39 +0200, Mateusz Paprocki a écrit :
> Hi,
>
> On 27 May 2011 20:33, krastano...@gmail.com
> <krastano...@gmail.com> wrote:
> I know (or I think I know) that eval(srepr(thing)) == thing in
> sympy.
>
>
> Yes, that should hold (otherwise it's a bug).
>
>
> Should this be also true for repr (the python build-in)? Why
> are there two different functions that should be doing the
> same thing? Is repr hard do modify?
>
That should be true as well - repr is supposed to behave like that. And
it's easy to implement: just define the __repr__ method to return the
right thing.

>
> In SymPy repr() == str() == sstr(). This has to work like this due to
> a bug in Python (see issue 2388 for more details).
>
What you mention is apparently a feature in Python, not a bug.


Vinzent Steinberg

unread,
May 28, 2011, 8:14:59 AM5/28/11
to sympy
On 27 Mai, 21:53, Ronan Lamy <ronan.l...@gmail.com> wrote:
> That should be true as well - repr is supposed to behave like that. And
> it's easy to implement: just define the __repr__ method to return the
> right thing.

For sure it is trivial to implement, but whether it is the right thing
is arguable. Personally, I surely don't want for example such
behavior:

>>> [x**4 - x**3*y - x*y**3 + y**4]
[Add(Mul(Integer(-1), Symbol('x'), Pow(Symbol('y'), Integer(3))),
Mul(Integer(-1), Symbol('y'), Pow(Symbol('x'), Integer(3)
)), Pow(Symbol('x'), Integer(4)), Pow(Symbol('y'), Integer(4)))]

> > In SymPy repr() == str() == sstr(). This has to work like this due to
> > a bug in Python (see issue 2388 for more details).
>
> What you mention is apparently a feature in Python, not a bug.

Well, call it "unwanted feature" if you prefer.

Vinzent

Ronan Lamy

unread,
May 28, 2011, 11:40:46 AM5/28/11
to sy...@googlegroups.com
Le samedi 28 mai 2011 à 05:14 -0700, Vinzent Steinberg a écrit :
> On 27 Mai, 21:53, Ronan Lamy <ronan.l...@gmail.com> wrote:
> > That should be true as well - repr is supposed to behave like that. And
> > it's easy to implement: just define the __repr__ method to return the
> > right thing.
>
> For sure it is trivial to implement, but whether it is the right thing
> is arguable. Personally, I surely don't want for example such
> behavior:
>
> >>> [x**4 - x**3*y - x*y**3 + y**4]
> [Add(Mul(Integer(-1), Symbol('x'), Pow(Symbol('y'), Integer(3))),
> Mul(Integer(-1), Symbol('y'), Pow(Symbol('x'), Integer(3)
> )), Pow(Symbol('x'), Integer(4)), Pow(Symbol('y'), Integer(4)))]

I don't care about that, because we don't put stuff inside containers
that often, because I usually want the repr when I look at .args, and
because the only shell I really care about is ipython, which prints this
nicely in any case.


>
> > > In SymPy repr() == str() == sstr(). This has to work like this due to
> > > a bug in Python (see issue 2388 for more details).
> >
> > What you mention is apparently a feature in Python, not a bug.
>
> Well, call it "unwanted feature" if you prefer.

What matters is that:
* we can't change it
* people new to sympy who know Python expect it
* there is a lot of code outside sympy that takes this behaviour for
granted and works with/around it.


Vinzent Steinberg

unread,
May 29, 2011, 11:25:23 AM5/29/11
to sympy
On 28 Mai, 17:40, Ronan Lamy <ronan.l...@gmail.com> wrote:
> I don't care about that, because we don't put stuff inside containers
> that often, because I usually want the repr when I look at .args, and
> because the only shell I really care about is ipython, which prints this
> nicely in any case.

I care about pure python shells. However, I could live with it if
there was a trivial way to setup printing as in isympy (calling
init_printing() probably already does this).

> What matters is that:
> * we can't change it
> * people new to sympy who know Python expect it
> * there is a lot of code outside sympy that takes this behaviour for
> granted and works with/around it.

On the other hand, eval(repr(x)) == x does not hold in general, see
for example lambda, functions, numpy arrays etc.

Vinzent

Ronan Lamy

unread,
May 29, 2011, 3:07:23 PM5/29/11
to sy...@googlegroups.com
Le dimanche 29 mai 2011 à 08:25 -0700, Vinzent Steinberg a écrit :
> On 28 Mai, 17:40, Ronan Lamy <ronan.l...@gmail.com> wrote:
> > I don't care about that, because we don't put stuff inside containers
> > that often, because I usually want the repr when I look at .args, and
> > because the only shell I really care about is ipython, which prints this
> > nicely in any case.
>
> I care about pure python shells. However, I could live with it if
> there was a trivial way to setup printing as in isympy (calling
> init_printing() probably already does this).
>
There is:

ronan@ronan-desktop:~/Projets/sympy-git$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from sympy import *
>>> import sys
>>> sys.displayhook = pprint
>>> class A(object):
... def __str__(self): return "A"
...
>>> A()
A
>>> [A()]
[A]
>>> str([A()])
[<__main__.A object at 0x9d2024c>]

> > What matters is that:
> > * we can't change it
> > * people new to sympy who know Python expect it
> > * there is a lot of code outside sympy that takes this behaviour for
> > granted and works with/around it.
>
> On the other hand, eval(repr(x)) == x does not hold in general, see
> for example lambda, functions, numpy arrays etc.

Sure. But what I meant by "this behaviour" is the fact that str() is
supposed to be the nice, human-friendly representation of the object,
while repr() shows what's actually inside the object, and that the str()
of built-in containers isn't actually nice enough for most uses.

Aaron Meurer

unread,
Jun 1, 2011, 10:12:34 PM6/1/11
to sy...@googlegroups.com
A few things:

- Even if we made isympy play nice, doctests assume just a regular
pure Python shell. So any doctest of a function that somehow has a
list, tuple, or dict of sympy objects would have to be changed to
either use less nice format (srepr()), or to use a printer that gets
around it.

- If we fix issue 2359, then I'd say about 90% of "typical" SymPy
expressions would work with eval(str(x)) == x, assuming that Symbols
have been instantiated (both str and srepr require "from sympy import
*"). And as we know, sympify(str(x)) == x should *always* work
assuming the expression is "generic" enough (i.e., standard functions
like sin() or exp() haven't been overridden, Symbols have default
assumptions, etc.).

srepr() also does things like Add(Symbol('x'), Symbol('y')) instead of
Symbol('x') + Symbol('y'), which I guess is more efficient so should
probably stay as long as srepr() is the *really* long form of an
expression.

- I use .args mainly to get at some part of an expression that I don't
want to re-type. If this always return the srepr() expression, that
would be useless. Granted, I always use isympy, which uses pprint,
not str, but I just wanted to point out that .args is not just used
for debugging.

- But even considering debugging, the srepr() form is, in my opinion,
less useful for SymPy expressions than str(). From what I gathered
from the discussions I saw on this on the Python mailing list and
elsewhere, SymPy is rather unique in the fact that str(expr) <
srepr(expr) by quite a bit for all but trivial expressions.
Pow(Add(Symbol('x'), Mul(Symbol('x'), Symbol('y')), Pow(Symbol('x'),
Integer(2))), Rational(1, 2)) is only more useful than sqrt(x**2 + x*y
+ x) if you want the eval(repr(x)) == x, which (unfortunately) doesn't
really apply in list/tuple/dict's calling of __repr__ with __str__.

Aaron Meurer

Ronan Lamy

unread,
Jun 1, 2011, 11:35:10 PM6/1/11
to sy...@googlegroups.com
Le mercredi 01 juin 2011 à 20:12 -0600, Aaron Meurer a écrit :
> A few things:
>
> - Even if we made isympy play nice, doctests assume just a regular
> pure Python shell. So any doctest of a function that somehow has a
> list, tuple, or dict of sympy objects would have to be changed to
> either use less nice format (srepr()), or to use a printer that gets
> around it.
>
Well, we're already running doctests under our own printer - that's why
we had to essentially fork doctest from the stdlib. I think bin/doctest
doesn't actually execute any __repr__() method from sympy objects.

OK, srepr(x**2 + x*y + x) is unreadable, but it could be improved by
indenting and falling back to a more condensed representation beyond a
certain depth in the expression tree. For instance:

Pow(
Add(Symbol('x'), Mul(x, y), Pow(x, 2)),
Rational(1, 2)
)

Aaron S. Meurer

unread,
Jun 2, 2011, 6:13:30 PM6/2/11
to sy...@googlegroups.com

But then what's the point? If you are going to have a bare x without Symbol(' ') around it why not just stick with the __str__ output, which is easy to read.

By the way, out of curiosity, what exactly are the uses of repr(). When do you need to be able to eval(repr(x))?

Aaron Meurer

Reply all
Reply to author
Forward
0 new messages