Hi!

Perhaps my question is too technical for sage-devel, but I hope to get
a clarification  or advice from you.

According to the doc string of sage.categories.map.Map.__call__:
"""
...
        - If ``x`` can be coerced into the domain of ``self``, then
the
          method ``_call_`` (single underscore) is called after
coercion.
        - Otherwise, it is tried to call the method ``pushout`` to
``x``
          (which may be provided in subclasses); in that way, ``self``
          could be applied to objects like ideals.
...
"""

However, it seems that the code does not reflect the description
above:
{{{
            if not PY_TYPE_CHECK(x, Element):
                return self._call_(x)
            elif (<Element>x)._parent is not self._domain:
                try:
                    x = self._domain(x)
                except TypeError:
                    try:
                        return self.pushforward(x)
                    except (TypeError, NotImplementedError):
                        raise ...
}}}

Nearly neglegible is the wrong wording: It is method "pushout"
according to the documentation, whereas it is method "pushforward" in
the code. So, the wording of the documentation should change.

But two or three things are really wrong:
(1) If the argument x is not an element then "_call_" is called,
although according to the description above one should expect that
"pushforward" was called.
(2) The method _call_ is not called after coercion but after
*conversion* into the domain.
(3) Why is coercion/conversion not used on input that is not an
element? Why is _call_ called directly, without coercion/conversion?

Example where (1) is annoying:
  sage: V0 = span([[1/2,0,0],[3/2,2,1],[0,0,1]],ZZ)
  sage: isinstance(V0,sage.structure.element.Element)
  False
We would like that a module morphism applied to a sub-module of the
domain yields a sub-module of the codomain, and this should be done in
the pushforward method. But since a sub-module is no element, it won't
work. I guess this is why module morphisms have a custom __call__
method.

Example where (2) is annoying:
  sage: K.<a>=NumberField(x^2-3,embedding=1)
  sage: L.<b>=NumberField(x^2-3)
  sage: K.has_coerce_map_from(L)
  False
  sage: K.coerce_embedding()(b)
  1.732050807568878?
K has no coercion from L, so, the conversion happening in the last
line should rather not be implicit.

Examples where (3) is annoying:
  sage: is_Element(int(1))
  False
  sage: is_Element([1,2,3])
  False
Certainly lists do not coerce into typical parent structures. But
often a conversion is possible. So, *if* one decides that implicit
conversion should happen: Why is conversion not applied to lists but
only to elements? And "int"s do coerce into many parent structures;
so, why is there no coercion before calling "_call_"?

I am considering to change the generic call method according to its
documentation: If parent(x) does not coerce into the domain, then
"pushforward" should be called; otherwise "_call_" should be called
after coercion.

However, that change would affect a large part of Sage, so I better
ask here whether there are people objecting. Are there?

Cheers,
Simon

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

Reply via email to