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 [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/
-~----------~----~----~----~------~----~------~--~---