[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