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?  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() ).

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


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
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/
-~----------~----~----~----~------~----~------~--~---

Reply via email to