[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