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

Reply via email to