[Python-ideas] Wild idea about mutability

Rob Cliffe rob.cliffe at btinternet.com
Thu Jun 2 09:05:10 EDT 2016



On 02/06/2016 02:34, Steven D'Aprano wrote:
> On Wed, Jun 01, 2016 at 11:26:07PM +0100, Rob Cliffe wrote:
>> I was prompted to post this after seeing comments on "Proposal to change
>> List Sequence Repetition (*) so it is not useless for Mutable Objects"
>> that you cannot in general tell whether an object is mutable or not.
>>
>> Well, why shouldn't you be able to tell?  Python is superb at
>> introspection, but ISTM there's a gap here.  Here's an idea for Python N
>> (N>=4):  Every object has a boolean __mutable__ attribute.  It would
>> e.g. be False for ints and strings,  True by default for objects that
>> can be mutable, such as lists and dicts.
> I hate to break it to you, but merely setting a flag on an object
> doesn't make it mutable or immutable *wink*
>
> That means that every class (possibly including builtins) needs to be
> re-written so that every mutator method checks this flag and decides
> whether or not to allow the mutation. For example, you suggest:
>
> "You don't need tuples.  You just have a list with __mutable__ = False."
>
> Now the code for list append must be:
>
>      def append(self, item):
>          # only written in C, because its a built-in
>          if self.__mutable__:
>              ...
>          else:
>              raise SomeError
>
> Now multiply that by *every* mutator class and method. This will be
> especially burdensome for people writing classes intended to be mutable,
> since they have to support immutability whether they want it or not.
>
> (Since the caller might change obj.__mutable__ to False, which is
> allowed.)
>
> This will break type-checking and duck-typing and make feature
> detection a pain:
>
> # currently this works
> if hasattr(obj, 'append'):
>      handle_things_that_can_append(obj)
> else:
>      handle_things_that_cant_append(obj)
>
> # with your scheme
> if hasattr(obj, 'append'):
>      if obj.__mutable__:
>          handle_things_that_can_append(obj)
>      else:
>          handle_things_that_cant_append(obj)
> else:
>      handle_things_that_cant_append(obj)
>
>
>> It could be an optional extra
>> argument to mutable object constructors (so you have the option of
>> making them immutable):
>>
>>      L = list(somesequence, mutable=False)
> This goes against the "no constant bool arguments" design guideline.
>
>
>> There could also be a syntax for list/set literals and dictionary
>> displays to indicate that they should be immutable (just as we preface
>> literal strings with 'r' to indicate raw strings).  I'm not sure what; I
>> thought of f[1,2,3] for a literal immutable ("frozen") list, but that's
>> already valid syntax.
> We already have syntax for a built-in immutable list-like sequence
> object (a "frozen list" if you will):
>
> (1, 2, 3)
>
>
>> You can "freeze" a mutable object by changing its __mutable__ attribute
>> from True to False.  You are not allowed to change it from False to
>> True, nor to mutate an object that has it False.
>>
>> I am sure there must be advantages in being able to tell if an object is
>> mutable or not.  (Perhaps "hashable" equals "not mutable" ?)
> No it does not.
>
> (1, 2, [3]) is both immutable and unhashable.
>
>
>> Now:  You don't need the frozenset class.  You just have a set with
>> __mutable__ = False.  And you can freeze dicts (classes? modules?) etc.,
>> to make sure users of your code don't mess with them.
> And we get this functionality for free, right? *wink*
>
> Somebody has to write this code. I'm not sure they will appreciate
> having to throw away all the perfectly good frozenset code and tests,
> and re-writing set to handle both cases. Not to mention the breaking of
> backwards compatibility to get rid of frozenset.
>
>
> [snip]
Sure, there are many difficulties.
This was intended to be a blue-sky idea.  I would like to pose the 
question "If I had to redesign Python from scratch, would I think this 
is a good idea?"
Rob



More information about the Python-ideas mailing list