On 9/27/07, Jason Grout <[EMAIL PROTECTED]> wrote: > In another thread ("making new infix operators", > http://groups.google.com/group/sage-devel/browse_thread/thread/a27ae5012d3754f5 > ), we evolved into a discussion of conventions for methods in SAGE. > I'll try to summarize and ask questions about this general subject here. > > First, I think it's important to have some sort of general consistency > in how methods are designed. It definitely helps the end-user know what > to expect and keeps the user from being surprised. Can we have some > official guidelines about how to design methods for objects? I've put > some thoughts below: > > Methods generally fall into several classes (did I miss a class?). > Given an object A, the method A.method(some parameters) could: > > > 1. Modify A (in-place) > 2. Return a new object based on A > 3. Ask a question of A > 3a. Ask a boolean question (answer is True or False) > 3b. Ask a more general question about A > > Cases 1 and 2 are discussed in the thread noted above. Which is > preferable?
Both. Both are needed in different contexts. The quintessential example of this in Python is lists versus tuples. lists are mutable and have several in-place methods. Tuples are *immutable* and have no inplace methods. One cannot compute the hash of a list, but one can compute the hash of a tuple, so lists can't be used as dictionary keys whereas tuples can. The short answer is that methods that change the object should *only* be used on mutable objects (e.g. lists), and immutable objects should never have methods that change the object. In most cases in mathematics immutable objects make more sense, and there is a strong preference toward immutability in Sage. There are also objects that -- for various reasons of usability -- start out as mutable, and can be made immutable. For example, matrices are by default mutable (so can be changed), but can be set immutable (which is irrevocable). > It seems that if we can count on a copy() method, then we > could make case 1 the convention and then case 2 would just be > A.copy().method(). I like this approach because it gives us both > worlds, but isn't too much syntax to do either one. It also allows the > (presumably fast) in-place modification by default. In these cases, I'd > prefer to have method() usually return the modified object so that we > could chain function calls (i.e., A.method().anothermethod() or > A.copy().method().anothermethod() ). This is too simplistic. You can't just make a choice between case 1 and case 2. Basically one has to follow what Python does. See above. With a particular type of objects you have to choose whether they are immutable or not (or have a way to become immutable), then do case 1 or case 2 accordingly based on mutability. Generally speaking, immutable is preferable since it is easier to reason about. > On 27 Sep 2007, in the thread mentioned above, Bill Page pointed out a > thread talking about in-place modifications by Robert Bradshaw (see > http://groups.google.com/group/sage-devel/browse_thread/thread/806cd958eb28ac3b/46655d7572d11ee6?#46655d7572d11ee6 > and http://www.sagemath.org:9002/sage_trac/ticket/624 ) that changes the > in-place versus return new copy discussion a bit. If I understand > things right, reference counting allows one to have (in Bill's words): > > [quote Bill Page] > > newgraph=A.union(B).union(C).union(D).union(E) > > would be done entirely in-place so that 'newgraph' becomes a modified > version of A, while in > > newgraph1=A.union(B).union(C).union(D).union(E) > newgraph2=A.union(B).union(C).union(D).union(E) > > a new copy of A is created and modified before it is assigned to > 'newgraph2'. However we do not have to be aware of this as such. The > only thing we need to remember is that there can be no side-effects. > > [/quote Bill Page] > > Questions: In the first example (or the second), is A changed? > > Fernando Perez points out where messing with reference counting can be > very tricky (using an example of numpy). > > Hamptonio points out a place where in-place modification can be > confusing, using the following example: > > [quote Hamptonio] > > Code version A: > a = something > b = [a,something_else] > c = a.a_method() > important_result(b) > > Code version B: > a = something > c = a.a_method() > b = [a,something_else] > important_result(b) > > ...although I might be confused. What I think would happen is that in > version A, under the proposed behavior a would not be modified in- > pace, but would be in version B. I can imagine this resulting in some > nasty bugs. Am I missing something? > [/quote Hamptonio] > > > I might point out that some languages have a naming convention for > functions that modify an object in-place. For example, in Lisp, a > function has a "!" at the end to help the user realize that the object > might change. It might be useful for us to either have a default > convention of in-place operators or have a naming convention that would > warn a user when in-place modifications would happen. Unless we can > somehow make the reference-counting magically work. > > > Case 3: > > In case 3, I think it's important to help the user realize that the > method is _only_ inquiring, but not touching or changing. Mathematica > has a naming convention for case (3a): any function asking a True/False > question ends in "Q". I think Lisp ends these functions in "?". Again, > for the user's sake, I think it would be nice to have some sort of > convention (naming or otherwise) signaling to the user that the function > is just asking a question, not modifying or touching the object. > > Thoughts or comments? Is there an official convention for these things? > > -Jason > > > > > -- William Stein Associate Professor of Mathematics University of Washington http://wstein.org --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---