[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