For most classes there isn't, but there can be. Using func instead of
type() allows objects to have a function that isn't its literal Python
class.  This is necessary, for instance, if you want to allow the
function to also be usable as an expression, since in that case it
would also have to be a Python object (not a class).

An example of this are the predicate objects, like Q.positive. We want
to be able to use both Q.positive and Q.positive(x) in logic
expressions. If Q.positive were the type() of Q.positive(x), this
would be impossible, because then Q.positive couldn't be an instance
of Basic.

So instead, it has its own type, and the .func is set appropriately:

In [20]: type(Q.positive(x))
Out[20]: sympy.assumptions.assume.AppliedPredicate

In [21]: Q.positive(x).func
Out[21]: Q.positive

Ideally we would like to do the same thing with functions as well
(https://github.com/sympy/sympy/issues/4787) so that it will be
possible to write things like cos + sin, and other "operator" like
expressions. sin + cos may end up not being a good idea, but as the
issue notes, something like D(f), where D is some kind of differential
operator, would be possible in this case (right now it isn't really
because f isn't an instance of Basic, so you can't just have D(f).args
== (f,)).

func has also been suggested as the way around issues with classes
that want to put non-Basic things in their args (particularly strings,
like with MatrixSymbol). Instead of MatrixSymbol('x', n, n).args ==
('x', n, n) as it is now, which is bad and breaks a lot of things
(because 'x' is not an instance of Basic), we would have
MatrixSymbol('x', n, n).args == (n, n) and MatrixSymbol('x', n,
n).func would be a special object that contains the 'x', which can
recreate the original MatrixSymbol('x', n, n).

Aaron Meurer

On Mon, Nov 9, 2015 at 12:07 PM, Francesco Bonazzi
<[email protected]> wrote:
> By the way, is there a real difference between type(self)(*args) and
> self.func(*args) ?
>
> On Monday, 9 November 2015 18:15:10 UTC+1, Aaron Meurer wrote:
>>
>> That's definitely a bug. Subclassing any class without changing
>> anything shouldn't break anything. There are unfortunately several
>> instances of this issue (see
>> https://github.com/sympy/sympy/issues/6751). Probably somewhere in
>> that code path something is referencing Add directly instead of using
>> self.func, or doing a type comparison without using isinstance.
>>
>> Aaron Meurer
>>
>> On Mon, Nov 9, 2015 at 10:48 AM, Duane Nykamp <[email protected]> wrote:
>> > OK, I'm pretty sure this is a bug.  I don't have to change Add at all to
>> > get
>> > this infinite recursion, just create any subclass
>> >
>> > In [7]: Add(3,3,evaluate=False).evalf()
>> > Out[7]: 6.00000000000000
>> >
>> > In [8]: class Add2(Add):
>> >    ...:     pass
>> >    ...:
>> >
>> > In [9]: Add2(3,3,evaluate=False).evalf()
>> > RuntimeError: maximum recursion depth exceeded
>> >
>> > I can't figure out where the code is treating Add and its identical
>> > subclass
>> > Add2 differently.
>> >
>> > Duane
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "sympy" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to [email protected].
>> > To post to this group, send email to [email protected].
>> > Visit this group at http://groups.google.com/group/sympy.
>> > To view this discussion on the web visit
>> >
>> > https://groups.google.com/d/msgid/sympy/60272dc0-8bf7-47db-83a9-01a840180943%40googlegroups.com.
>> >
>> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/fe2324dd-75b8-4f14-a21b-f9fcb192b2c5%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAKgW%3D6JhaEiig4J0NqR4K%2Bi80Jn%2BYnzpbCBKb73y%3DLc_G4kX9w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to