unify usage of mutable and immutable objects

Hi! I write a '<'-based immutable set class. But it is quit different from the standard set class. I wish collections.abc.Set be more friendly to immutable tree sets or Python add new syntax to unify such difference. good example: a = [] a += a # "a" is the original list a = () a += a # "a" is a new tuple bad example: a = set() a.add(1) # return None; "a" changed e = a.pop(); a = frozen_tree_set() a = a.add(1) # return another set; e, a = a.ipop() # return two objects instead of one! solution I used: a <<= 1 # <==> a = a.add(1) but "a.ipop()" .... my current solution is to write a wrapper class to turn immutable set into mutable set, but it is so noisy to box and unbox. solution that I wish: a :=.add(1) # "=." mimic "+="; return the result object e ~ a :=.pop() d[key] :=.add(1) # in dict if only python add following features: 1) modify the original object 1-0) 1) define: def .method(self):... # "." means "intend to modify self" # return any thing # to avoid immutable method # which was intended to return new object # leave self unchanged 2) invoke: r = a..method(); 1-1) ignore result # no matter what returned, discard it a.-.method(); # <==> [a..method(), None][-1] 1-2) return self # no matter what returned, return self a.>.method().>.method();# <==> [a..method(), a..method(), a][-1] 2) create new object 2-0) 1) define # intend to return (result, new object) def ^method():... 2)invoke: r, a' = a.^method(); 2-1) return other, discard result a.-^method().-^method();# <==> a.^method()[1].^method()[1]; 2-2) assign other to original variable a=^method(); # <==> a = a.^method()[1]; 3) unify both: a :=.method(); # if defined ".method" then "a..method();" # elif defined "^method" then "a = a.^method()[1];" # elif defined "method" then "a.method();" # else error r ~ a :=.method(); # if defined ".method" then "r = a..method();" # elif defined "^method" then "r, a = a.^method();" # elif defined "method" then "r = a.method();" # else error

but what is frozen_tree_set() here, frozen_tree_set is my set class.
what is ipop? when we pop element from frozensets, we get a element and a new set.
At 2017-02-28 23:19:03, "Ryan Birmingham" <rainventions@gmail.com> wrote: I'm sorry for the confusion, but what is frozen_tree_set() here, and what is ipop? frozensets don't have pop or 'ipop', so my apologies that I'm a bit lost here. -Ryan Birmingham On 28 February 2017 at 08:59, 语言破碎处 <mlet_it_bew@126.com> wrote: Hi! I write a '<'-based immutable set class. But it is quit different from the standard set class. I wish collections.abc.Set be more friendly to immutable tree sets or Python add new syntax to unify such difference. good example: a = [] a += a # "a" is the original list a = () a += a # "a" is a new tuple bad example: a = set() a.add(1) # return None; "a" changed e = a.pop(); a = frozen_tree_set() a = a.add(1) # return another set; e, a = a.ipop() # return two objects instead of one! solution I used: a <<= 1 # <==> a = a.add(1) but "a.ipop()" .... my current solution is to write a wrapper class to turn immutable set into mutable set, but it is so noisy to box and unbox. solution that I wish: a :=.add(1) # "=." mimic "+="; return the result object e ~ a :=.pop() d[key] :=.add(1) # in dict if only python add following features: 1) modify the original object 1-0) 1) define: def .method(self):... # "." means "intend to modify self" # return any thing # to avoid immutable method # which was intended to return new object # leave self unchanged 2) invoke: r = a..method(); 1-1) ignore result # no matter what returned, discard it a.-.method(); # <==> [a..method(), None][-1] 1-2) return self # no matter what returned, return self a.>.method().>.method();# <==> [a..method(), a..method(), a][-1] 2) create new object 2-0) 1) define # intend to return (result, new object) def ^method():... 2)invoke: r, a' = a.^method(); 2-1) return other, discard result a.-^method().-^method();# <==> a.^method()[1].^method()[1]; 2-2) assign other to original variable a=^method(); # <==> a = a.^method()[1]; 3) unify both: a :=.method(); # if defined ".method" then "a..method();" # elif defined "^method" then "a = a.^method()[1];" # elif defined "method" then "a.method();" # else error r ~ a :=.method(); # if defined ".method" then "r = a..method();" # elif defined "^method" then "r, a = a.^method();" # elif defined "method" then "r = a.method();" # else error _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

So it sounds like what you want is this: In [30]: class FrozenSet(frozenset): ...: def pop(self): ...: item = next(iter(self)) ...: return item, self-{item} ...: In [31]: a = FrozenSet({1,2,3,4,5}) In [32]: a.pop() Out[32]: (1, frozenset({2, 3, 4, 5})) I think I'm +1 on `frozenset` itself growing that method. On Tue, Feb 28, 2017 at 10:13 AM, 语言破碎处 <mlet_it_bew@126.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Tue, Feb 28, 2017 at 1:49 PM, Terry Reedy <tjreedy@udel.edu> wrote:
Yeah, I guess you are right. I was thinking that having a compatible API for sets and frozensets would be good. But this really isn't it anyway. `.pop()` is one of those few standard library methods that is used for simultaneous mutation and return value. My FrozenSet class does something quite different with the method; possibly something useful enough to have under a different name, but it doesn't help with duck typing set-like objects. The OP suggests: Pop tuple/frozenset(standard one) gain no benefit. # O(n)
It is a different story for balanced tree. # O(log n)
This is true. You can make a slightly changed copy of an immutable tree in O(log N) time since most pointers are to existing subtrees. But then, pretty much everything else one does is also O(log N) which loses to the O(1) of most set operations. But that's moot for Python. A custom class implementing a balanced tree is free to define its own semantics for a `.pop()` method. This is a very different data structure than Python's set/frozenset which are based on hashes. We are not going to change the implementation of sets so fundamentally, mostly because having O(1) behaviors is so nice (add, remove, membership check, etc). -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Tue, Feb 28, 2017 at 5:59 AM, 语言破碎处 <mlet_it_bew@126.com> wrote:
That is simply misspelled for your intent. a = set() a |= {1} e = a.pop() -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

That is simply misspelled for your intent.
Take a look at the following function in Haskell (GHC) Data.Set minView :: Set a -> Maybe (a, Set a) We always want the new set after a immutable set pop(). "e = a.pop()" is fine for mutable set, but not for immutable case. we need "e, a = a.pop()" to update "a". 在 2017-03-01 01:23:54,"David Mertz" <mertz@gnosis.cx> 写道: On Tue, Feb 28, 2017 at 5:59 AM, 语言破碎处 <mlet_it_bew@126.com> wrote: bad example: a = set() a.add(1) # return None; "a" changed e = a.pop(); That is simply misspelled for your intent. a = set() a |= {1} e = a.pop() -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

but what is frozen_tree_set() here, frozen_tree_set is my set class.
what is ipop? when we pop element from frozensets, we get a element and a new set.
At 2017-02-28 23:19:03, "Ryan Birmingham" <rainventions@gmail.com> wrote: I'm sorry for the confusion, but what is frozen_tree_set() here, and what is ipop? frozensets don't have pop or 'ipop', so my apologies that I'm a bit lost here. -Ryan Birmingham On 28 February 2017 at 08:59, 语言破碎处 <mlet_it_bew@126.com> wrote: Hi! I write a '<'-based immutable set class. But it is quit different from the standard set class. I wish collections.abc.Set be more friendly to immutable tree sets or Python add new syntax to unify such difference. good example: a = [] a += a # "a" is the original list a = () a += a # "a" is a new tuple bad example: a = set() a.add(1) # return None; "a" changed e = a.pop(); a = frozen_tree_set() a = a.add(1) # return another set; e, a = a.ipop() # return two objects instead of one! solution I used: a <<= 1 # <==> a = a.add(1) but "a.ipop()" .... my current solution is to write a wrapper class to turn immutable set into mutable set, but it is so noisy to box and unbox. solution that I wish: a :=.add(1) # "=." mimic "+="; return the result object e ~ a :=.pop() d[key] :=.add(1) # in dict if only python add following features: 1) modify the original object 1-0) 1) define: def .method(self):... # "." means "intend to modify self" # return any thing # to avoid immutable method # which was intended to return new object # leave self unchanged 2) invoke: r = a..method(); 1-1) ignore result # no matter what returned, discard it a.-.method(); # <==> [a..method(), None][-1] 1-2) return self # no matter what returned, return self a.>.method().>.method();# <==> [a..method(), a..method(), a][-1] 2) create new object 2-0) 1) define # intend to return (result, new object) def ^method():... 2)invoke: r, a' = a.^method(); 2-1) return other, discard result a.-^method().-^method();# <==> a.^method()[1].^method()[1]; 2-2) assign other to original variable a=^method(); # <==> a = a.^method()[1]; 3) unify both: a :=.method(); # if defined ".method" then "a..method();" # elif defined "^method" then "a = a.^method()[1];" # elif defined "method" then "a.method();" # else error r ~ a :=.method(); # if defined ".method" then "r = a..method();" # elif defined "^method" then "r, a = a.^method();" # elif defined "method" then "r = a.method();" # else error _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/

So it sounds like what you want is this: In [30]: class FrozenSet(frozenset): ...: def pop(self): ...: item = next(iter(self)) ...: return item, self-{item} ...: In [31]: a = FrozenSet({1,2,3,4,5}) In [32]: a.pop() Out[32]: (1, frozenset({2, 3, 4, 5})) I think I'm +1 on `frozenset` itself growing that method. On Tue, Feb 28, 2017 at 10:13 AM, 语言破碎处 <mlet_it_bew@126.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Tue, Feb 28, 2017 at 1:49 PM, Terry Reedy <tjreedy@udel.edu> wrote:
Yeah, I guess you are right. I was thinking that having a compatible API for sets and frozensets would be good. But this really isn't it anyway. `.pop()` is one of those few standard library methods that is used for simultaneous mutation and return value. My FrozenSet class does something quite different with the method; possibly something useful enough to have under a different name, but it doesn't help with duck typing set-like objects. The OP suggests: Pop tuple/frozenset(standard one) gain no benefit. # O(n)
It is a different story for balanced tree. # O(log n)
This is true. You can make a slightly changed copy of an immutable tree in O(log N) time since most pointers are to existing subtrees. But then, pretty much everything else one does is also O(log N) which loses to the O(1) of most set operations. But that's moot for Python. A custom class implementing a balanced tree is free to define its own semantics for a `.pop()` method. This is a very different data structure than Python's set/frozenset which are based on hashes. We are not going to change the implementation of sets so fundamentally, mostly because having O(1) behaviors is so nice (add, remove, membership check, etc). -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Tue, Feb 28, 2017 at 5:59 AM, 语言破碎处 <mlet_it_bew@126.com> wrote:
That is simply misspelled for your intent. a = set() a |= {1} e = a.pop() -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

That is simply misspelled for your intent.
Take a look at the following function in Haskell (GHC) Data.Set minView :: Set a -> Maybe (a, Set a) We always want the new set after a immutable set pop(). "e = a.pop()" is fine for mutable set, but not for immutable case. we need "e, a = a.pop()" to update "a". 在 2017-03-01 01:23:54,"David Mertz" <mertz@gnosis.cx> 写道: On Tue, Feb 28, 2017 at 5:59 AM, 语言破碎处 <mlet_it_bew@126.com> wrote: bad example: a = set() a.add(1) # return None; "a" changed e = a.pop(); That is simply misspelled for your intent. a = set() a |= {1} e = a.pop() -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
participants (4)
-
David Mertz
-
Ryan Birmingham
-
Terry Reedy
-
语言破碎处