#10963: More functorial constructions
-------------------------------------+-------------------------------------
Reporter: nthiery | Owner: stumpc5
Type: enhancement | Status: needs_review
Priority: major | Milestone: sage-6.1
Component: categories | Resolution:
Keywords: days54 | Merged in:
Authors: Nicolas M. Thiéry | Reviewers: Simon King, Frédéric
Report Upstream: N/A | Chapoton
Branch: | Work issues:
public/ticket/10963 | Commit:
Dependencies: #11224, #8327, | 8045aa4a4b7ada735b3eb6055382f9b341a39f1e
#10193, #12895, #14516, #14722, | Stopgaps:
#13589, #14471, #15069, #15094, |
#11688, #13394, #15150, #15506 |
-------------------------------------+-------------------------------------
Comment (by nthiery):
Replying to [comment:389 vbraun]:
> You are parsing the "Finite" class name, I don't care if it is explicit
using string tools/regexes or implicit looking for classes whose names
match certain strings. The usual way is to provide a programmatic
interface that sets up stuff in code. You should avoid using strings for
program flow, and most certainly not use them for foundational material. I
wouldn't care so much if we were talking about some implementation details
in the combinat project, but you expect us to go around and teach others
to use this. That better have a really good reason for the current
interface. **Simple** would be something that follows usual patterns (even
if its a few characters more). I don't see anything simple here, I see a
bunch of trickery that is extremely hard to understand by looking at the
code.
>
> And you don't need operations on axioms? I see a lot of weird stuff in
this ticket where you use strings to do operations that would be much
clearer if you had some object to represent the axiom. E.g.:
> {{{
> sage: FiniteFields()._without_axiom("Commutative")
> }}}
> vs.
> {{{
> sage: FiniteFields().without(Commutative())
> sage: FiniteFields() - Commutative()
> }}}
I will change this example to {{{FiniteFields() + Commutative()}}} so
as to speak of an operation which is clearly useful in real life.
The syntax:
{{{
FiniteFields().Commutative()
}}}
has the following merits:
- No need to import stuff. From a single entry point (e.g. the
category of Fields()), you can explore all categories you can get
from it by just following the flow of calling methods.
- Want to know what are the available axioms? Well, constructing the
subcategory of objects satisfying the Finite axiom is a natural
operation on a category; therefore, in a standard OO pattern you
find this operations along the other methods. Just use
introspection:
{{{
sage: C = Monoids()
sage: C.<tab>
}}}
(as pointed by Nils, you could refine this to recover exactly the
axioms)
- Tab completion naturally reduces to exactly those axioms that are
applicable in the given context.
- Which file implements the commutativity axiom? Use introspection:
{{{
sage: Monoids().Finite.__module__
'sage.categories.sets_cat'
}}}
- Where is the documentation for the `Commutative` axiom? Use
introspection:
{{{
sage: C = Monoids()
sage: C.Finite?
}}}
- Somewhat unrelated, but since you asked elsewhere. How do you know
which mixins get inserted when you use a given axiom? Use
introspection::
{{{
sage: Groups().Finite().parent_class.mro()
[sage.categories.finite_groups.FiniteGroups.parent_class,
sage.categories.finite_monoids.FiniteMonoids.parent_class,
sage.categories.groups.Groups.parent_class,
sage.categories.monoids.Monoids.parent_class,
sage.categories.finite_semigroups.FiniteSemigroups.parent_class,
sage.categories.semigroups.Semigroups.parent_class,
sage.categories.magmas.Unital.Inverse.parent_class,
sage.categories.magmas.Magmas.Unital.parent_class,
sage.categories.magmas.Magmas.parent_class,
sage.categories.finite_enumerated_sets.FiniteEnumeratedSets.parent_class,
sage.categories.enumerated_sets.EnumeratedSets.parent_class,
sage.categories.finite_sets.FiniteSets.parent_class,
sage.categories.sets_cat.Sets.parent_class,
sage.categories.sets_with_partial_maps.SetsWithPartialMaps.parent_class,
sage.categories.objects.Objects.parent_class,
object]
}}}
Besides I would not want to use arithmetic for the operation of adding
an axiom, since mathematically we would not write this using
arithmetic either, but that's a minor detail.
Yes there is a bit of complexity under the hood. Implementing a mixins
mechanism in a language that does not support it natively means that
you have to do some non trivial stuff. The internals of an interpreter
are not simple either. It does not necessarily means that it's
complicated to use in practice.
<grin>
Oh but right, in Python, methods and attributes are accessed by
looking up for strings in the dictionary of the classes/objects.
Overriding a method means inserting a string in a dictionary. Yuck!
Maybe we should not be using methods and attributes at all in our
code?
</grin>
> Its an absolute no-brainer in Python to model **everything** with
objects. If I have an object then I can tell immediately. Lets keep it
simple and explicit, yes. Shorter but non-discoverable is most certainly
not simpler. And explicit is better than implicit, as always.
The axiom is basically already modeled by a *method*. That's rather
simple and explicit. And introspection works rather naturally.
Maybe we could go a bit further and indeed use objects instead of
strings in the _with(...) methods and in the output of .axioms(). But
please, go ahead, try it in a non trivial project and see if it really
makes things easier to use in practice. It's not clear.
I am happy leaving a note that this piece of the design is an
implementation detail and subject to refactoring.
> Also, I don't agree with atomicity in setting
`_base_category_class_and_axiom` buys us anything. Its private by
convention, so it is the job of the setter to make changes atomically if
necessary (though thats hardly an issue in Python). But in multi-threaded
Java, say, this would be a bad data structure as well. We all know the old
joke, whats the only data structure in Cobol? A 2000-character EBCDIC
string...
<getting frustrated>
Whatever. That's a minor implementation detail I don't care about. Not
happy with it? Go ahead, fix it and get everything right. I spent
weeks polishing everything to a state where it works smoothly. This
patch has been advertised for quite some time now, and already got
positively reviewed featurewise months ago. Time to move on.
</getting frustrated>
Nicolas
--
Ticket URL: <http://trac.sagemath.org/ticket/10963#comment:397>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" 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/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.