[Python-ideas] "Immutable Builder" Pattern and Operator

Alexandre Brault abrault at mapgears.com
Mon Jan 23 13:27:24 EST 2017



On 2017-01-23 12:54 PM, Soni L. wrote:
> On 23/01/17 02:56 PM, Gerald Britton wrote:
>> On Jan 23, 2017 11:07 AM, "Soni L." <fakedme+py at gmail.com
>> <mailto:fakedme%2Bpy at gmail.com>> wrote:
>>
>>     On 23/01/17 01:52 PM, Gerald Britton wrote:
>>>
>>>         [snip]
>>>
>>>          
>>>
>>>         >I propose `x .= y` -> `x = x . y`, for any `y`.
>>>
>>>          
>>>
>>>         [snip]
>>>
>>>          
>>>
>>>         I think you mean "any y that is a member of x"
>>>
>>
>>     Since it desugars into `x = x.y`, you can literally use anything
>>     for `y`.
>>
>>     x .= __call__().whatever().unwrap() * 3
>>
>>     is equivalent to
>>
>>     x = x.__call__().whatever().unwrap() * 3
>>
>>     and
>>
>>     x .= 1
>>
>>     is equivalent to
>>
>>     x = x.1
>>
>>     which is equivalent to
>>
>>     SyntaxError: invalid syntax
>>
>>
>>>          
>>>
>>>         Also, note that this syntax means that x will be rebound to
>>>         the result of calling x.y, whatever that is (frequently,
>>>         None, for mutating methods)
>>>
>>>         In general, you can't count on methods to return references
>>>         to their instances, even though it's handy for fluent
>>>         coding, so this side effect may be unexpected to some
>>>
>>
>>     This is why it's for use with **immutable** objects.
>>
>>
>>>          
>>>
>>>         That's a problem with your original example:
>>>
>>>          
>>>
>>>         >long_name = mkbuilder()
>>>
>>>         >long_name = long_name.seta(a)
>>>
>>>         >long_name = long_name.setb(b)
>>>
>>>         >y = long_name.build()
>>>
>>>          
>>>
>>>         What do the methods seta and setb return?  If they don't
>>>         return "self" you've got a problem. I think.
>>>
>>
>>     They don't return self. Ever. The value bound to long_name is
>>     immutable, like an integer. They return a new instance.
>>
>>
>> Then long_name isn't immutable. It changes with every line. That can
>> lead to nasty bugs if you count on its immutability.
>>
>> Easy to see. Just print long_name after each call.
>
> You're mixing up value immutability with name immutability. The name
> isn't immutable, but:
>
> long_name = mkbuilder()
> x = long_name
> long_name .= seta("a")
> y = long_name
> long_name .= setb("b")
> z = long_name
> print(x)  # a = None, b = None
> print(y)  # a = "a", b = None
> print(z)  # a = "a", b = "b"
> print(x is y)  # False
> print(x is z)  # False
> print(y is z)  # False
> print(long_name is z)  # True
This is a really contrived example that doesn't need a special syntax.
Consider instead:

>>> x = mkbuilder()
>>> y = x.seta('a')
>>> z = y.setb('b')
>>> long_name = z

All your prints work as well, this is much easier to mentally parse
(notwithstanding the unpythonesque builder pattern) and doesn't require
the addition of a new syntax that people more knowledgeable than me have
already explained is not a good idea

--Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170123/c6dca5a0/attachment-0001.html>


More information about the Python-ideas mailing list