On Jan 10, 2010, at 3:15 AM, Simon King wrote:
Hi Nathann and Robert!
I was thinking about the huge list of functions we have at the
moment
in the Graph class, and the length of Graph.py.
I am a bit puzzled: Do you really talk about *functions*? Should there
be any function *at all*, except for constructors?
Or are you talking about *methods*?
My thoughts as well. I think the two are being confused.
This way, when we use tab completion on "g." or on "Graph.", see the
module "clique" , on which we could then use tab completion again
through "Graph.clique."
This won't work for methods, as the functions in clique won't get a
bound self.
Again, perhaps I don't properly understand. Is the plan as follows?
- There are certain *functions* "def foobar(self)" defined in
Graph.clique
- A graph instance has methods that essentially just call the
functions from Graph.clique
- You want to have tab completion for these methods
If this is what you intend:
- You may have a __getattr__ method for graphs. Whenever an attribute
of a graph is requested that starts with "clique_" (say,
g.clique_foobar) then __getattr__ returns the corresponding function
from clique (here: the function foobar). In that way, the zillions of
functions/methods could be neatly distributed/sorted into various
files, and it is straight forward to extend.
- For obtaining tab completion: IIRC, it suffices if __getattr__
returns a list of available method names (e.g. "clique_foobar") if the
attribute __methods__ (or was it __members__?) is requested.
If it's a question of splitting it up into files, this can already be
done, and in a much simpler way.
cdef class Graph:
from clique import max_clique
now if max_clique is a function, then this code will make it an
ordinary method as if it were defined here.
I.e. you'd have to write
sage: g.trees.is_tree(g)
unless you did some trickery behind the scenes.
Perhaps the above is the trickery? Although I used those things for
elements of infinite polynomial rings, I am still not sure if it
doesn't qualify as a nasty hack, though.
What one would have to do is have trees be an object that references g
(via __getattr__ or initialized on every graph creation). Then trees
in turn would have a __getattr__ that would take the method from the
right module (either looking up in all, or via a list, or a cleverer
algorithm--note that max_clique doesn't start with clique) and bind it
to g and then return the resulting method. Given that all we're trying
to do is lookup and bind known methods, which Python does without any
work, it seems a bit much (not to mention there are efficiency and
subclassing concerns).
I would actually find this interface less easy to use--the fact that
you're asking for any discussion about where functions should go
means
that it's not 100% obvious, so an end user might end up having to
search multiple subspaces to find the method desired method--or even
to see a method doesn't exist. Namespaces can be good, but usually
only when there's an actual hierarchy.
sage: import this
The Zen of Python, by Tim Peters
...
Flat is better than nested.
...
And this is why it shouldn't be functions but methods?
If it's a question of file length, that can be split up without
changing the interface. If it's a concern of overwhelming the user
with too many methods on g.[tab], I think the answer is to make tab
completion smarter (e.g. g.iso[tab] could find is_isomorphism).
Note that this would not be covered by the above trickery ("let
__getattr__ return the list of function names if __methods__ is
requested"); it would be needed to work on tab completion per se.
I wonder if this is a nice feature, though. Imagine you do "g.i<TAB>"
-- should it really return *all* method names that *contain* (rather
than start with) an "i"? This wouldn't be helpful, IMHO.
I was thinking it would return all names that start with "i" or
contain "_i", so "g.clique<tab>" would return "max_clique." This would
also solve the left/right_X issue for matrices. Maybe it would require
two tabs to get.
- Robert
--
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