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

Reply via email to