[sage-devel] Depreciated is_AlgebraElement function

24 views
Skip to first unread message

Starx

unread,
Mar 26, 2012, 2:06:53 AM3/26/12
to sage-devel
I was looking at the function is_AlgebraElement which needs a doctest.
When I called it in sage (to come up with a doctest) I got a
depreciation warning:

sage: is_AlgebraElement(e)
/Users/Starx/sage-dev/local/bin/sage-ipython:1: DeprecationWarning:
Using is_AlgebraElement from the top level is deprecated since it was
designed to be used by developers rather than end users.
It most likely does not do what you would expect it to do. If you
really need to use it, import it from the module that it is defined
in.
#!/usr/bin/env python
False

Which brings up three questions:

1) How are functions depreciated? I ran
search_src("is_AlgebraElement") and looked at all the results and I
can only find this function occurring in either its definition or in
import statements. How does sage know to print a depreciation warning
for this function?

2) What is sage's philosophy when depreciating? Is this to be
eventually deleted? And if so why not delete it now, as it isn't used
anywhere else in the source.

Finally 3) What's with all the is_Something(x) functions anyway? As
far as I can see they always just return isinstance(x, Something). Is
it because we don't expect a user to know the python isinstance
function?

-Jim

--
Die Dunkelheit... leitet die Musik.
Die Musik... leitet die Seele.

Mike Hansen

unread,
Mar 26, 2012, 2:19:04 AM3/26/12
to sage-...@googlegroups.com
On Sun, Mar 25, 2012 at 11:06 PM, Starx <jst...@gmail.com> wrote:
> 1) How are functions depreciated?  I ran
> search_src("is_AlgebraElement") and looked at all the results and I
> can only find this function occurring in either its definition or in
> import statements.  How does sage know to print a depreciation warning
> for this function?

See sage/all.py -- they are only deprecated from Sage's "global
namespace" in order to avoid users seeing things like

sage: is_Integer(int(2))
False

> 2) What is sage's philosophy when depreciating?  Is this to be
> eventually deleted?  And if so why not delete it now, as it isn't used
> anywhere else in the source.

Yes, they should probably be removed from the global namespace in Sage
5.0 as that deprecation warning has been there quite awhile.

> Finally 3) What's with all the is_Something(x) functions anyway?  As
> far as I can see they always just return isinstance(x, Something).  Is
> it because we don't expect a user to know the python isinstance
> function?

They were from awhile back, but I think it's better to just use
isinstance directly.

--Mike

Simon King

unread,
Mar 26, 2012, 5:27:28 AM3/26/12
to sage-...@googlegroups.com
Hi!

On 2012-03-26, Mike Hansen <mha...@gmail.com> wrote:
> On Sun, Mar 25, 2012 at 11:06 PM, Starx <jst...@gmail.com> wrote:
>> 1) How are functions depreciated?
>

> See sage/all.py

Namely

message = "\nUsing %(name)s from the top level is deprecated since it was designed to be used by developers rather than end users.\nIt most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in."
sage.misc.misc.deprecated_callable_import(None, globals(), locals(),
[name for name in globals().keys()
if name.startswith('is_') and name[3].isupper()], message)


>> Finally 3) What's with all the is_Something(x) functions anyway?  As
>> far as I can see they always just return isinstance(x, Something).  Is
>> it because we don't expect a user to know the python isinstance
>> function?
>
> They were from awhile back, but I think it's better to just use
> isinstance directly.

Yes and no. For example, before Sage had its category framework, one
could assume that all rings are instances of sage.rings.ring.Ring and
all principal ideal domains are instances of
sage.rings.principal_ideal_domain.PrincipalIdealDomain.

However, nowadays, for testing whether something is a ring resp. a
principal ideal domain, it is really not a good idea to use isinstance. Better do
X in Rings()
resp.
X in PrincipalIdealDomains()

Also note that by some recent patch, the recommended way of testing properties
is not only better from a mathematical point of view, but it is also
**faster** (at least if we are talking about a category without a base
ring):

(with sage-5.0.beta8)
sage: X = QQ['x']
sage: Y = QQ['x','y']
sage: isinstance(X,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
True
sage: isinstance(Y,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
False
sage: PID = PrincipalIdealDomains()
sage: X in PID
True
sage: Y in PID
False
sage: %timeit isinstance(X,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
625 loops, best of 3: 984 ns per loop
sage: %timeit X in PID
625 loops, best of 3: 816 ns per loop
sage: %timeit isinstance(Y,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
625 loops, best of 3: 1.97 µs per loop
sage: %timeit Y in PID
625 loops, best of 3: 1.02 µs per loop


If you find an example in sage-5.0 where this gives the wrong answer,
then please report!

Cheers,
Simon

Simon King

unread,
Mar 26, 2012, 5:31:54 AM3/26/12
to sage-...@googlegroups.com
PS:

On 2012-03-26, Simon King <simon...@uni-jena.de> wrote:
> Also note that by some recent patch, the recommended way of testing properties
> is not only better from a mathematical point of view, but it is also
> **faster** (at least if we are talking about a category without a base
> ring):
>
> (with sage-5.0.beta8)

> ...


> sage: %timeit isinstance(X,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
> 625 loops, best of 3: 984 ns per loop
> sage: %timeit X in PID
> 625 loops, best of 3: 816 ns per loop
> sage: %timeit isinstance(Y,sage.rings.principal_ideal_domain.PrincipalIdealDomain)
> 625 loops, best of 3: 1.97 µs per loop
> sage: %timeit Y in PID
> 625 loops, best of 3: 1.02 µs per loop

And I forgot to add the comparison with the deprecated function
is_PrincipalIdealDomain, which is of course even slower than calling
isinstance directly.

Note that I explicitly import the function, in order to avoid the
deprecation warning:
sage: from sage.rings.principal_ideal_domain import is_PrincipalIdealDomain
sage: %timeit is_PrincipalIdealDomain(X)
625 loops, best of 3: 1.03 µs per loop
sage: %timeit is_PrincipalIdealDomain(Y)
625 loops, best of 3: 1.9 µs per loop

Cheers,
Simon

Simon King

unread,
Mar 26, 2012, 5:48:13 AM3/26/12
to sage-...@googlegroups.com
Hi!

On 2012-03-26, Mike Hansen <mha...@gmail.com> wrote:

> On Sun, Mar 25, 2012 at 11:06 PM, Starx <jst...@gmail.com> wrote:
> See sage/all.py -- they are only deprecated from Sage's "global
> namespace" in order to avoid users seeing things like
>
> sage: is_Integer(int(2))
> False

Since I talked about timings in my previous post...

The "correct" way of testing whether something is an
integer is clearly slower than the deprecated way,
but I think it is still acceptable:
sage: from sage.rings.integer import is_Integer
sage: n = 5
sage: %timeit is_Integer(5)
sage: %timeit is_Integer(n)
625 loops, best of 3: 198 ns per loop
sage: %timeit n in ZZ
625 loops, best of 3: 283 ns per loop

Note that the deprecation warning explicitly states that you are likely
to get "unexpected" results when using this function (namely, when you
expect that the behaviour of this function has a mathematical meaning),
and here you are:
sage: is_Integer(int(5))
False
sage: is_Integer(5/1)
False
sage: int(5) in ZZ
True
sage: 5/1 in ZZ
True

So, if you want to know whether something is (equal to) an integer,
regardless of the type, then "x in ZZ" is the way to go, even though it
is slower.

Cheers,
Simon


Keshav Kini

unread,
Mar 26, 2012, 12:32:45 PM3/26/12
to sage-...@googlegroups.com
Simon King <simon...@uni-jena.de> writes:
> sage: is_Integer(int(5))
> False
> sage: is_Integer(5/1)
> False
> sage: int(5) in ZZ
> True
> sage: 5/1 in ZZ
> True

Huh. It seems like this is the opposite of what you'd expect, doesn't
it? "object in object" seems to be a query of whether a certain thing is
in a certain data structure, i.e. seems like it should be
literal-type-aware, whereas "semantic_function_name(object)" seems more
likely to have a mathematical, abstract meaning.

-Keshav

----
Join us in #sagemath on irc.freenode.net !

John H Palmieri

unread,
Mar 26, 2012, 1:13:20 PM3/26/12
to sage-...@googlegroups.com


On Monday, March 26, 2012 9:32:45 AM UTC-7, Keshav Kini wrote:
Simon King writes:
>   sage: is_Integer(int(5))
>   False
>   sage: is_Integer(5/1)
>   False
>   sage: int(5) in ZZ
>   True
>   sage: 5/1 in ZZ
>   True

Huh. It seems like this is the opposite of what you'd expect, doesn't
it? "object in object" seems to be a query of whether a certain thing is
in a certain data structure, i.e. seems like it should be
literal-type-aware, whereas "semantic_function_name(object)" seems more
likely to have a mathematical, abstract meaning.

The functions like "is_Integer" are deprecated. If you compare the alternative

   isinstance(5/1, Integer)

with

   5/1 in ZZ

I definitely want the first to return False, and I'm also happy if the second returns True. It makes more sense to me for the second to have a mathematical, abstract, meaning, because it is more natural and more likely for a user to execute. I think we should view our users as mathematicians first, so I like things as they are.

(Another way to say it is that "x in Y" should take coercions and related operations into account, as "5/1 in ZZ" does. If there is a canonical one-to-one map from S to T, then every element of S should be "in" T.  Every element of a group should be "in" the corresponding group algebra, etc.)

--
John

Keshav Kini

unread,
Mar 26, 2012, 1:18:01 PM3/26/12
to sage-...@googlegroups.com
John H Palmieri <jhpalm...@gmail.com> writes:
> The functions like "is_Integer" are deprecated. If you compare the alternative
>
> isinstance(5/1, Integer)
>
> with
>
> 5/1 in ZZ
>
> I definitely want the first to return False, and I'm also happy if the second
> returns True. It makes more sense to me for the second to have a mathematical,
> abstract, meaning, because it is more natural and more likely for a user to
> execute. I think we should view our users as mathematicians first, so I like
> things as they are.
>
> (Another way to say it is that "x in Y" should take coercions and related
> operations into account, as "5/1 in ZZ" does. If there is a canonical
> one-to-one map from S to T, then every element of S should be "in" T. Every
> element of a group should be "in" the corresponding group algebra, etc.)

Once you change is_Integer(5/1) to isinstance(5/1, Integer), it becomes
abundantly clear which one is the literal containment check and which is
the mathematical containment check. So I guess what it boils down to is
that we should get rid of deprecated stuff :)

Simon King

unread,
Mar 27, 2012, 4:14:52 AM3/27/12
to sage-...@googlegroups.com
Hi Keshav,

On 2012-03-26, Keshav Kini <kesha...@gmail.com> wrote:
> Simon King <simon...@uni-jena.de> writes:
>> sage: is_Integer(int(5))
>> False
>> sage: is_Integer(5/1)
>> False
>> sage: int(5) in ZZ
>> True
>> sage: 5/1 in ZZ
>> True
>
> Huh. It seems like this is the opposite of what you'd expect, doesn't
> it? "object in object" seems to be a query of whether a certain thing is
> in a certain data structure,

I couldn't disagree more. "object in object" is a query whether a
certain thing is in a certain *mathematical* structure.

Cheers,
Simon

leif

unread,
Mar 27, 2012, 10:48:17 AM3/27/12
to sage-devel
On 27 Mrz., 10:14, Simon King <simon.k...@uni-jena.de> wrote:
> Hi Keshav,
>
> On 2012-03-26, Keshav Kini <keshav.k...@gmail.com> wrote:
>
> > Simon King <simon.k...@uni-jena.de> writes:
> >>   sage: is_Integer(int(5))
> >>   False
> >>   sage: is_Integer(5/1)
> >>   False
> >>   sage: int(5) in ZZ
> >>   True
> >>   sage: 5/1 in ZZ
> >>   True
>
> > Huh. It seems like this is the opposite of what you'd expect, doesn't
> > it? "object in object" seems to be a query of whether a certain thing is
> > in a certain data structure,
>
> I couldn't disagree more. "object in object" is a query whether a
> certain thing is in a certain *mathematical* structure.

You're probably confusing 'in' and '\in'... ;-)


More importantly, what happens if coercion etc. fails? Will Sage then
potentially make false mathematical statements, or raise an
exception / return "unknown" or "undecidable" etc.?


-leif

David Roe

unread,
Mar 27, 2012, 10:55:59 AM3/27/12
to sage-...@googlegroups.com
More importantly, what happens if coercion etc. fails?  Will Sage then
potentially make false mathematical statements, or raise an
exception / return "unknown" or "undecidable" etc.

No.  It catches the ValueErrors and TypeErrors, and returns False (so ZZ['x'].gen() is not in QQ).
David

Starx

unread,
Mar 27, 2012, 1:06:48 PM3/27/12
to sage-...@googlegroups.com
There are 260 functions defined in Sage of the form def is_Name(x)
where Name starts with a capitol letter (my script didn't count the
cdef functions so there might actually be more). Of those 110 of them
simply return isinstance(x, Name) and I think those 110 can definitely
be deleted. Deleting them and replacing all there calls with calls to
isinstance and all there imports with imports of Name is not something
I'd like to do by hand, so I'm working on a script that will do it.

As for the other 150, some of them do the following:

def is_Name(x)
return isinstance(x, Name_something)

I didn't check but I suspect that there is a factory called Name which
is why the _whatever is there. Another example of this issue is that
is_Cone(x) returns isinstance(x, ConvexRationalPolyhedralCone) and the
function Cone constructs ConvexRationalPolyhedraCones. I'm undecided
on whether we should remove these is_functions as well. Is the user
expected to know that the factory is just a factory? and look through
the source code to figure out what the class name is?

Finally there are some is_functions that return something slightly
more complicated then a single isinstance, for example

def is_PrimeFiniteField(x):
some imports

return isinstance(x, FiniteField_prime_modn) or \
(isinstance(x, FiniteField_generic) and x.degree() == 1)

I would probably just leave these alone, any arguments to the contrary?

-Jim

> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to
> sage-devel+...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org

Starx

unread,
Mar 27, 2012, 1:30:59 PM3/27/12
to sage-...@googlegroups.com
Actually I think deleting the is_functions deserves it's own thread,
so ignore my last message and see:
http://groups.google.com/group/sage-devel/browse_thread/thread/e8c2470e270f616b

-Jim

Reply all
Reply to author
Forward
0 new messages