On Sep 27, 2007, at 4:43 AM, Jason Grout wrote:

> Mike Hansen wrote:
>>> The best I've come up with at this point is, given graphs  
>>> A,B,C,D,E, the
>>> union is:
>>>
>>> A.union(B).union(C).union(D).union(E)
>>>
>>> where the union function returns the modified graph each time so  
>>> I can
>>> keep chaining union function calls.  The union actually modifies the
>>> graph A, so if you want A left alone and a new graph returned,  
>>> you do:
>>>
>>> newgraph=A.copy().union(B).union(C).union(D).union(E)
>>>
>>> Comments?  Is there a better way to do things?
>>
>> I think A.union(B) should leave A and B unchanged and return a new
>> graph object since that's pretty much how everything else works in
>> Python. In-place operations feel very out-of-place ;-)
>
> That's what I always thought to.  But then I saw the Python sort()
> function, or the reverse() function, etc. and grudgingly accepted that
> the python way was to modify things in place.

Yes, but note that sort and reverse don't return anything, which I  
think is a good convention. You don't have to worry about having two  
objects, and wondering if they're actually the same thing (as you do  
with an inplace operator that returns self).

> In the end, I want two options: to modify things in-place or to  
> return a
> new object.  I also want some sort of consistency so that the user  
> isn't
> constantly guessing what a function will do.  After playing with  
> things
> for a bit, I decided that the easiest consistent thing to do was to
> modify in-place and call A.copy().whatever() when I wanted to return a
> new object.  That way a copy was explicitly denoted with somewhat
> minimal syntax, the general case was consistent, and we still had  
> access
> to both options.
>
> Would you suggest doing things the other way?  Return a new copy by
> default and always have:
>
> A=A.union(B)
>
> to modify A?

Yes. Or even

A.inplace_union(B)

(or some better name than that) which returns nothing. Otherwise, for  
example, every function that received a graph as an argument would  
have to make a copy to avoid side effects (or the calling function  
would always have to make a copy before passing in just in case).  
Explicitly making a copy everywhere seems cumbersome.

> It's slightly worse performance-wise, it seems, because we
> are always making copies and throwing old copies away.  Especially  
> if we
> have the above (A.union(B).union(C).union(D).union(E))---then we  
> make 4
> new copies of things and throw away all but 1 of them.

True, this is the price to pay. It might be worth having a function  
that does things inplace if one needs the speed, but I like to avoid  
side effects in general. Though I think the syntax above is the  
clearest, A.union([B,C,D]) could be done more efficiently.

- Robert


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