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

Soni L. fakedme+py at gmail.com
Mon Jan 23 12:54:05 EST 2017



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

See also:

long_name = 1
x = long_name
long_name += 1
y = long_name
long_name += 1
z = long_name
print(x)  # 1
print(y)  # 2
print(z)  # 3
print(x is y)  # False
print(x is z)  # False
print(y is z)  # False
print(long_name is z)  # True
>
>
>
>>         FWIW why can't you just write:
>>
>>         x.y
>>
>>         or for your example:
>>
>>         long_name.seta(a)
>>
>>         ?
>>
>>
>
>     See the IRC bot builder example, it should be more clear. (It's
>     about forking the builder.)
>
>

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


More information about the Python-ideas mailing list