<p dir="ltr">Paul Moore is clearly right when He says that this "a .= 1+1" doesn't make sense. It means nothing understandable although in "a .= s(e)" can mean something. As a matter of fact "a .= EXPR" is bound to succeed only in a very small set of cases.</p>
<div class="gmail_quote">On Jan 23, 2017 14:39, <<a href="mailto:python-ideas-request@python.org">python-ideas-request@python.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Send Python-ideas mailing list submissions to<br>
<a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
or, via email, send a message with subject or body 'help' to<br>
<a href="mailto:python-ideas-request@python.org">python-ideas-request@python.<wbr>org</a><br>
<br>
You can reach the person managing the list at<br>
<a href="mailto:python-ideas-owner@python.org">python-ideas-owner@python.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of Python-ideas digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
1. Re: "Immutable Builder" Pattern and Operator (Paul Moore)<br>
2. Re: "Immutable Builder" Pattern and Operator (Soni L.)<br>
3. Re: Python-ideas Digest, Vol 122, Issue 81 (Herv? Kyle MUTOMBO)<br>
<br>
<br>
------------------------------<wbr>------------------------------<wbr>----------<br>
<br>
Message: 1<br>
Date: Mon, 23 Jan 2017 13:26:49 +0000<br>
From: Paul Moore <<a href="mailto:p.f.moore@gmail.com">p.f.moore@gmail.com</a>><br>
To: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>><br>
Cc: Python-Ideas <<a href="mailto:python-ideas@python.org">python-ideas@python.org</a>><br>
Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
Message-ID:<br>
<CACac1F9qo=<a href="mailto:1Zr7-YW%2BrCYBCQMV7cu7BRC9WrCR3ZNMkJ%2BE8iQA@mail.gmail.com">1Zr7-YW+<wbr>rCYBCQMV7cu7BRC9WrCR3ZNMkJ+<wbr>E8iQA@mail.gmail.com</a>><br>
Content-Type: text/plain; charset=UTF-8<br>
<br>
On 23 January 2017 at 13:05, Soni L. <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>> wrote:<br>
> Yeah but the dotequals operator has many other benefits:<br>
><br>
> long_name .= __call__ # cast to callable<br>
> long_name .= wrapped # unwrap<br>
> etc<br>
<br>
Those don't seem particularly clear to me.<br>
<br>
> And it also looks neat.<br>
<br>
Well, we have to agree to differ on that one.<br>
<br>
Also, the semantics of the proposed operation are very odd. If I<br>
understand your proposal<br>
<br>
a .= b(c)<br>
<br>
doesn't evaluate b(c) (It can't, as b is a method of a and doesn't<br>
make sense on its own), but rather combines the LHS and RHS with a dot<br>
- so it's defined in terms of rewriting the input rather than as an<br>
operation on the subexpressions. There's no other operator in Python<br>
that I'm aware of that works like this.<br>
<br>
What grammar would you allow for the RHS? So far you've shown<br>
<br>
LHS .= METHOD(ARGS)<br>
LHS .= ATTRIBUTE<br>
<br>
Clearly,<br>
<br>
LHS .= EXPR<br>
<br>
makes no sense in general (consider a .= 1+1).<br>
<br>
On the other hand, what about<br>
<br>
LHS .= ATTRIBUTE[INDEX]<br>
<br>
? I'm guessing you'd want that allowed?<br>
<br>
Frankly, I don't think the benefits are even close to justifying the complexity.<br>
<br>
Paul<br>
<br>
<br>
------------------------------<br>
<br>
Message: 2<br>
Date: Mon, 23 Jan 2017 11:33:26 -0200<br>
From: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>><br>
To: "M.-A. Lemburg" <<a href="mailto:mal@egenix.com">mal@egenix.com</a>><br>
Cc: "<a href="mailto:python-ideas@python.org">python-ideas@python.org</a>" <<a href="mailto:python-ideas@python.org">python-ideas@python.org</a>><br>
Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
Message-ID: <<a href="mailto:e36e68d0-826f-db35-af31-11b330c57226@gmail.com">e36e68d0-826f-db35-af31-<wbr>11b330c57226@gmail.com</a>><br>
Content-Type: text/plain; charset=windows-1252; format=flowed<br>
<br>
... I need a better email client. *double-checks I got everything right<br>
this time...*<br>
<br>
On 23/01/17 11:30 AM, Soni L. wrote:<br>
> Sorry, I replied to this wrong. Not used to this mailing list.<br>
><br>
> On 23/01/17 11:28 AM, Soni L. wrote:<br>
>><br>
>><br>
>> On 23/01/17 11:18 AM, M.-A. Lemburg wrote:<br>
>>> On 23.01.2017 14:05, Soni L. wrote:<br>
>>>><br>
>>>> On 23/01/17 09:45 AM, Serhiy Storchaka wrote:<br>
>>>>> On 23.01.17 01:30, Soni L. wrote:<br>
>>>>>> On 22/01/17 08:54 PM, Serhiy Storchaka wrote:<br>
>>>>>>> On 23.01.17 00:45, Soni L. wrote:<br>
>>>>>>>> I've been thinking of an Immutable Builder pattern and an operator<br>
>>>>>>>> to go<br>
>>>>>>>> with it. Since the builder would be immutable, this wouldn't work:<br>
>>>>>>>><br>
>>>>>>>> long_name = mkbuilder()<br>
>>>>>>>> long_name.seta(a)<br>
>>>>>>>> long_name.setb(b)<br>
>>>>>>>> y = long_name.build()<br>
>>>>>>> I think the more pythonic way is:<br>
>>>>>>><br>
>>>>>>> y = build(a=a, b=b)<br>
>>>>>>><br>
>>>>>>> A Builder pattern is less used in Python due to the support of<br>
>>>>>>> keyword<br>
>>>>>>> arguments.<br>
>>>>>> I guess you could do something like this, for an IRC bot builder:<br>
>>>>>><br>
>>>>>> fnircbotbuilder = mkircbotbuilder(network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.<wbr>freenode.net</a>",<br>
>>>>>> port=6697,<br>
>>>>>> ssl=true)<br>
>>>>>> mainbot = mkircbotbuilder(parent=<wbr>fnircbotbuilder, # ???<br>
>>>>>> channels=["#bots"]).build()<br>
>>>>>> fndccbotbuilder = mkircbotbuilder(parent=<wbr>fnircbotbuilder, dcc=true,<br>
>>>>>> channeldcc=true)<br>
>>>>>> dccbot = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
>>>>>> channels=["#ctcp-s"]).build()<br>
>>>>>> otherircbotbuilder = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
>>>>>> network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>") # because we want this whole network<br>
>>>>>> otherbot = mkircbotbuilder(parent=<wbr>otherircbotbuilder,<br>
>>>>>> channels=["#programming"]).<wbr>build() # to use DCC and channel DCC<br>
>>>>>><br>
>>>>>> But this would be cleaner:<br>
>>>>>><br>
>>>>>> botbuilder =<br>
>>>>>> mkircbotbuilder().network("<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc<wbr>.freenode.net</a>").port(6697).<wbr>ssl(true)<br>
>>>>>> mainbot = botbuilder.channels(["#bots"])<wbr>.build()<br>
>>>>>> botbuilder .= dcc(true).channeldcc(true)<br>
>>>>>> dccbot = botbuilder.channels(["#ctcp-s"<wbr>]).build()<br>
>>>>>> botbuilder .= network("<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
>>>>>> otherbot = botbuilder.channels(["#<wbr>programming"]).build()<br>
>>>>> In Python you can save common options in a dict and pass them as<br>
>>>>> var-keyword argument. Or use functools.partial. In any case you don't<br>
>>>>> need a builder class with the build method and a number of<br>
>>>>> configuring<br>
>>>>> methods. It can be just a function with optional keyword parameters.<br>
>>>>><br>
>>>>> A Builder pattern is often used in languages that don't support<br>
>>>>> passing arguments by keyword and partial functions. Python rarely<br>
>>>>> needs the purposed class implementing a Builder pattern. Actually a<br>
>>>>> Builder pattern is built-in in the language as a part of syntax.<br>
>>>>><br>
>>>> Yeah but the dotequals operator has many other benefits:<br>
>>>><br>
>>>> long_name .= __call__ # cast to callable<br>
>>>> long_name .= wrapped # unwrap<br>
>>>> etc<br>
>>>><br>
>>>> And it also looks neat.<br>
>>> I don't see this an being a particular intuitive way of writing<br>
>>> such rather uncommon constructs.<br>
>>><br>
>>> The syntax is not clear (what if you have an expression on the RHS)<br>
>>> and it doesn't save you much in writing (if long_name is too long<br>
>>> simply rebind it under a shorter name for the purpose of the code<br>
>>> block).<br>
>><br>
>> It's literally sugar for repeating the name and moving the dot to the<br>
>> right. I think it's clearer than most other compound operators in<br>
>> that it doesn't affect precedence rules.<br>
>><br>
>> `x += y`, for any code `y`, is equivalent to `x = x + (y)`, not `x =<br>
>> x + y`.<br>
>><br>
>> `x .= y`, for any code `y`, is equivalent to `x = x . y`, not `x = x<br>
>> . (y)`.<br>
>><br>
>>><br>
>>> Also note that rebinding different objects to the same name<br>
>>> in the same block is often poor style and can easily lead to<br>
>>> hard to track bugs.<br>
>>><br>
>><br>
>> Rebinding different objects to the same name in rapid succession is<br>
>> fine.<br>
><br>
<br>
<br>
------------------------------<br>
<br>
Message: 3<br>
Date: Mon, 23 Jan 2017 14:38:40 +0100<br>
From: Herv? "Kyle" MUTOMBO <<a href="mailto:hervinhioslash@gmail.com">hervinhioslash@gmail.com</a>><br>
To: <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
Subject: Re: [Python-ideas] Python-ideas Digest, Vol 122, Issue 81<br>
Message-ID:<br>
<<a href="mailto:CAKX-YRBEy%2Bjf713qP4GY%2BQ6HFwMGXxHNKNSLpVPf34T-z%2BPecg@mail.gmail.com">CAKX-YRBEy+jf713qP4GY+<wbr>Q6HFwMGXxHNKNSLpVPf34T-z+Pecg@<wbr>mail.gmail.com</a>><br>
Content-Type: text/plain; charset="utf-8"<br>
<br>
Pleasing to see and somehow elegant. I believe .= is a good idea.<br>
On Jan 23, 2017 14:18, <<a href="mailto:python-ideas-request@python.org">python-ideas-request@python.<wbr>org</a>> wrote:<br>
<br>
> Send Python-ideas mailing list submissions to<br>
> <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
><br>
> To subscribe or unsubscribe via the World Wide Web, visit<br>
> <a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
> or, via email, send a message with subject or body 'help' to<br>
> <a href="mailto:python-ideas-request@python.org">python-ideas-request@python.<wbr>org</a><br>
><br>
> You can reach the person managing the list at<br>
> <a href="mailto:python-ideas-owner@python.org">python-ideas-owner@python.org</a><br>
><br>
> When replying, please edit your Subject line so it is more specific<br>
> than "Re: Contents of Python-ideas digest..."<br>
><br>
><br>
> Today's Topics:<br>
><br>
> 1. Re: "Immutable Builder" Pattern and Operator (Cory Benfield)<br>
> 2. Re: "Immutable Builder" Pattern and Operator (Paul Moore)<br>
> 3. Re: "Immutable Builder" Pattern and Operator (Serhiy Storchaka)<br>
> 4. Re: "Immutable Builder" Pattern and Operator (Soni L.)<br>
> 5. Re: "Immutable Builder" Pattern and Operator (M.-A. Lemburg)<br>
><br>
><br>
> ------------------------------<wbr>------------------------------<wbr>----------<br>
><br>
> Message: 1<br>
> Date: Mon, 23 Jan 2017 09:32:02 +0000<br>
> From: Cory Benfield <<a href="mailto:cory@lukasa.co.uk">cory@lukasa.co.uk</a>><br>
> To: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>><br>
> Cc: <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
> Message-ID: <<a href="mailto:8671EBCA-148F-41C8-A592-46EF653B9CAE@lukasa.co.uk">8671EBCA-148F-41C8-A592-<wbr>46EF653B9CAE@lukasa.co.uk</a>><br>
> Content-Type: text/plain; charset="utf-8"<br>
><br>
><br>
> > On 22 Jan 2017, at 22:45, Soni L. <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>> wrote:<br>
> ><br>
> ><br>
><br>
> This pattern is present in the cryptography module already with things<br>
> like their x509.CertificateBuilder: <a href="https://cryptography.io/en/" rel="noreferrer" target="_blank">https://cryptography.io/en/</a><br>
> latest/x509/reference/#<wbr>cryptography.x509.<wbr>CertificateBuilder <<br>
> <a href="https://cryptography.io/en/latest/x509/reference/#cryptography.x509" rel="noreferrer" target="_blank">https://cryptography.io/en/<wbr>latest/x509/reference/#<wbr>cryptography.x509</a>.<br>
> CertificateBuilder>.<br>
><br>
> My 2c, but I find that code perfectly readable and legible. I don?t think<br>
> a dot-equals operator would be needed.<br>
><br>
> Cory<br>
> -------------- next part --------------<br>
> An HTML attachment was scrubbed...<br>
> URL: <<a href="http://mail.python.org/pipermail/python-ideas/" rel="noreferrer" target="_blank">http://mail.python.org/<wbr>pipermail/python-ideas/</a><br>
> attachments/20170123/c4e7d09f/<wbr>attachment-0001.html><br>
><br>
> ------------------------------<br>
><br>
> Message: 2<br>
> Date: Mon, 23 Jan 2017 09:54:55 +0000<br>
> From: Paul Moore <<a href="mailto:p.f.moore@gmail.com">p.f.moore@gmail.com</a>><br>
> To: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>><br>
> Cc: Python-Ideas <<a href="mailto:python-ideas@python.org">python-ideas@python.org</a>><br>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
> Message-ID:<br>
> <CACac1F9CcDEyNuvGBSNSpm+U0=<wbr>VQNaN9Yd-Mgj+q_Uk16gxGfQ@mail.<br>
> <a href="http://gmail.com" rel="noreferrer" target="_blank">gmail.com</a>><br>
> Content-Type: text/plain; charset=UTF-8<br>
><br>
> On 22 January 2017 at 22:45, Soni L. <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>> wrote:<br>
> > I've been thinking of an Immutable Builder pattern and an operator to go<br>
> > with it. Since the builder would be immutable, this wouldn't work:<br>
> ><br>
> > long_name = mkbuilder()<br>
> > long_name.seta(a)<br>
> > long_name.setb(b)<br>
> > y = long_name.build()<br>
> ><br>
> > Instead, you'd need something more like this:<br>
> ><br>
> > long_name = mkbuilder()<br>
> > long_name = long_name.seta(a)<br>
> > long_name = long_name.setb(b)<br>
> > y = long_name.build()<br>
> ><br>
> > Or we could add an operator to simplify it:<br>
> ><br>
> > long_name = mkbuilder()<br>
> > long_name .= seta(a)<br>
> > long_name .= setb(b)<br>
> > y = long_name.build()<br>
> ><br>
> > (Yes, I'm aware you can x = mkbuilder().seta(a).setb(b), then y =<br>
> x.build().<br>
> > But that doesn't work if you wanna "fork" the builder. Some builders,<br>
> like a<br>
> > builder for network connections of some sort, would work best if they<br>
> were<br>
> > immutable/forkable.)<br>
><br>
> I don't think the .= operator adds enough to be worth it. If the<br>
> problem you see is the duplication of long_name in those lines (it's<br>
> difficult to be sure without a real example) then you can use a<br>
> temporary:<br>
><br>
> b = mkbuilder()<br>
> b = b.seta(a)<br>
> b = b.setb(b)<br>
> long_name = b<br>
> y = long_name.build()<br>
><br>
> For your real example:<br>
><br>
> On 22 January 2017 at 23:30, Soni L. <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>> wrote:<br>
> > fnircbotbuilder = mkircbotbuilder(network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.<wbr>freenode.net</a>", port=6697,<br>
> > ssl=true)<br>
> > mainbot = mkircbotbuilder(parent=<wbr>fnircbotbuilder, # ???<br>
> > channels=["#bots"]).build()<br>
> > fndccbotbuilder = mkircbotbuilder(parent=<wbr>fnircbotbuilder, dcc=true,<br>
> > channeldcc=true)<br>
> > dccbot = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> > channels=["#ctcp-s"]).build()<br>
> > otherircbotbuilder = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> > network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>") # because we want this whole network<br>
> > otherbot = mkircbotbuilder(parent=<wbr>otherircbotbuilder,<br>
> > channels=["#programming"]).<wbr>build() # to use DCC and channel DCC<br>
> ><br>
> > But this would be cleaner:<br>
> ><br>
> > botbuilder =<br>
> > mkircbotbuilder().network("<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc<wbr>.freenode.net</a>").port(6697).<wbr>ssl(true)<br>
> > mainbot = botbuilder.channels(["#bots"])<wbr>.build()<br>
> > botbuilder .= dcc(true).channeldcc(true)<br>
> > dccbot = botbuilder.channels(["#ctcp-s"<wbr>]).build()<br>
> > botbuilder .= network("<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
> > otherbot = botbuilder.channels(["#<wbr>programming"]).build()<br>
><br>
> I don't find the second example appreciably cleaner than the first.<br>
> But a bit of reformatting looks better to me:<br>
><br>
> # First create builders for the bots<br>
> fnircbotbuilder = mkircbotbuilder(<br>
> network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.freenode.net</a>",<br>
> port=6697,<br>
> ssl=true)<br>
> fndccbotbuilder = mkircbotbuilder(<br>
> parent=fnircbotbuilder,<br>
> dcc=true,<br>
> channeldcc=true)<br>
> otherircbotbuilder = mkircbotbuilder(<br>
> parent=fndccbotbuilder,<br>
> network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
><br>
> # Now create the actual bots<br>
> mainbot = mkircbotbuilder(<br>
> parent=fnircbotbuilder,<br>
> channels=["#bots"]).build()<br>
> dccbot = mkircbotbuilder(<br>
> parent=fndccbotbuilder,<br>
> channels=["#ctcp-s"]).build()<br>
> otherbot = mkircbotbuilder(<br>
> parent=otherircbotbuilder,<br>
> channels=["#programming"]).<wbr>build()<br>
><br>
> And some API redesign (make the builders classes, and the parent<br>
> relationship becomes subclassing, and maybe make channels an argument<br>
> to build() so that you don't need fresh builders for each of the<br>
> actual bots, and you don't even need the "builder" in the name at this<br>
> point) makes the whole thing look far cleaner (to me, at least):<br>
><br>
> class FNIRCBot(IRCBot):<br>
> network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.freenode.net</a>"<br>
> port=6697<br>
> ssl=True<br>
> class FNDCCBot(FNIRCBot):<br>
> dcc=True<br>
> channeldcc=True<br>
> class OtherIRCBot(IRCBot):<br>
> network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>"<br>
><br>
> mainbot = FNIRCBot(channels=["#bots"])<br>
> dccbot = FNDCCBot(channels=["#ctcp-s"])<br>
> otherbot = OtherIRCBot(channels=["#<wbr>programming"])<br>
><br>
> Paul<br>
><br>
><br>
> ------------------------------<br>
><br>
> Message: 3<br>
> Date: Mon, 23 Jan 2017 13:45:18 +0200<br>
> From: Serhiy Storchaka <<a href="mailto:storchaka@gmail.com">storchaka@gmail.com</a>><br>
> To: <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
> Message-ID: <o64qc9$k3q$<a href="mailto:1@blaine.gmane.org">1@blaine.gmane.org</a><wbr>><br>
> Content-Type: text/plain; charset=windows-1252; format=flowed<br>
><br>
> On 23.01.17 01:30, Soni L. wrote:<br>
> > On 22/01/17 08:54 PM, Serhiy Storchaka wrote:<br>
> >> On 23.01.17 00:45, Soni L. wrote:<br>
> >>> I've been thinking of an Immutable Builder pattern and an operator to<br>
> go<br>
> >>> with it. Since the builder would be immutable, this wouldn't work:<br>
> >>><br>
> >>> long_name = mkbuilder()<br>
> >>> long_name.seta(a)<br>
> >>> long_name.setb(b)<br>
> >>> y = long_name.build()<br>
> >><br>
> >> I think the more pythonic way is:<br>
> >><br>
> >> y = build(a=a, b=b)<br>
> >><br>
> >> A Builder pattern is less used in Python due to the support of keyword<br>
> >> arguments.<br>
> ><br>
> > I guess you could do something like this, for an IRC bot builder:<br>
> ><br>
> > fnircbotbuilder = mkircbotbuilder(network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.<wbr>freenode.net</a>", port=6697,<br>
> > ssl=true)<br>
> > mainbot = mkircbotbuilder(parent=<wbr>fnircbotbuilder, # ???<br>
> > channels=["#bots"]).build()<br>
> > fndccbotbuilder = mkircbotbuilder(parent=<wbr>fnircbotbuilder, dcc=true,<br>
> > channeldcc=true)<br>
> > dccbot = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> > channels=["#ctcp-s"]).build()<br>
> > otherircbotbuilder = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> > network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>") # because we want this whole network<br>
> > otherbot = mkircbotbuilder(parent=<wbr>otherircbotbuilder,<br>
> > channels=["#programming"]).<wbr>build() # to use DCC and channel DCC<br>
> ><br>
> > But this would be cleaner:<br>
> ><br>
> > botbuilder =<br>
> > mkircbotbuilder().network("<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc<wbr>.freenode.net</a>").port(6697).<wbr>ssl(true)<br>
> > mainbot = botbuilder.channels(["#bots"])<wbr>.build()<br>
> > botbuilder .= dcc(true).channeldcc(true)<br>
> > dccbot = botbuilder.channels(["#ctcp-s"<wbr>]).build()<br>
> > botbuilder .= network("<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
> > otherbot = botbuilder.channels(["#<wbr>programming"]).build()<br>
><br>
> In Python you can save common options in a dict and pass them as<br>
> var-keyword argument. Or use functools.partial. In any case you don't<br>
> need a builder class with the build method and a number of configuring<br>
> methods. It can be just a function with optional keyword parameters.<br>
><br>
> A Builder pattern is often used in languages that don't support passing<br>
> arguments by keyword and partial functions. Python rarely needs the<br>
> purposed class implementing a Builder pattern. Actually a Builder<br>
> pattern is built-in in the language as a part of syntax.<br>
><br>
><br>
><br>
><br>
> ------------------------------<br>
><br>
> Message: 4<br>
> Date: Mon, 23 Jan 2017 11:05:12 -0200<br>
> From: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>><br>
> To: <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
> Message-ID: <<a href="mailto:e9f1547f-c5a6-045a-8716-7669a1662b32@gmail.com">e9f1547f-c5a6-045a-8716-<wbr>7669a1662b32@gmail.com</a>><br>
> Content-Type: text/plain; charset=windows-1252; format=flowed<br>
><br>
><br>
><br>
> On 23/01/17 09:45 AM, Serhiy Storchaka wrote:<br>
> > On 23.01.17 01:30, Soni L. wrote:<br>
> >> On 22/01/17 08:54 PM, Serhiy Storchaka wrote:<br>
> >>> On 23.01.17 00:45, Soni L. wrote:<br>
> >>>> I've been thinking of an Immutable Builder pattern and an operator<br>
> >>>> to go<br>
> >>>> with it. Since the builder would be immutable, this wouldn't work:<br>
> >>>><br>
> >>>> long_name = mkbuilder()<br>
> >>>> long_name.seta(a)<br>
> >>>> long_name.setb(b)<br>
> >>>> y = long_name.build()<br>
> >>><br>
> >>> I think the more pythonic way is:<br>
> >>><br>
> >>> y = build(a=a, b=b)<br>
> >>><br>
> >>> A Builder pattern is less used in Python due to the support of keyword<br>
> >>> arguments.<br>
> >><br>
> >> I guess you could do something like this, for an IRC bot builder:<br>
> >><br>
> >> fnircbotbuilder = mkircbotbuilder(network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.<wbr>freenode.net</a>",<br>
> port=6697,<br>
> >> ssl=true)<br>
> >> mainbot = mkircbotbuilder(parent=<wbr>fnircbotbuilder, # ???<br>
> >> channels=["#bots"]).build()<br>
> >> fndccbotbuilder = mkircbotbuilder(parent=<wbr>fnircbotbuilder, dcc=true,<br>
> >> channeldcc=true)<br>
> >> dccbot = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> >> channels=["#ctcp-s"]).build()<br>
> >> otherircbotbuilder = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> >> network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>") # because we want this whole network<br>
> >> otherbot = mkircbotbuilder(parent=<wbr>otherircbotbuilder,<br>
> >> channels=["#programming"]).<wbr>build() # to use DCC and channel DCC<br>
> >><br>
> >> But this would be cleaner:<br>
> >><br>
> >> botbuilder =<br>
> >> mkircbotbuilder().network("<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc<wbr>.freenode.net</a>").port(6697).<wbr>ssl(true)<br>
> >> mainbot = botbuilder.channels(["#bots"])<wbr>.build()<br>
> >> botbuilder .= dcc(true).channeldcc(true)<br>
> >> dccbot = botbuilder.channels(["#ctcp-s"<wbr>]).build()<br>
> >> botbuilder .= network("<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
> >> otherbot = botbuilder.channels(["#<wbr>programming"]).build()<br>
> ><br>
> > In Python you can save common options in a dict and pass them as<br>
> > var-keyword argument. Or use functools.partial. In any case you don't<br>
> > need a builder class with the build method and a number of configuring<br>
> > methods. It can be just a function with optional keyword parameters.<br>
> ><br>
> > A Builder pattern is often used in languages that don't support<br>
> > passing arguments by keyword and partial functions. Python rarely<br>
> > needs the purposed class implementing a Builder pattern. Actually a<br>
> > Builder pattern is built-in in the language as a part of syntax.<br>
> ><br>
> Yeah but the dotequals operator has many other benefits:<br>
><br>
> long_name .= __call__ # cast to callable<br>
> long_name .= wrapped # unwrap<br>
> etc<br>
><br>
> And it also looks neat.<br>
><br>
><br>
> ------------------------------<br>
><br>
> Message: 5<br>
> Date: Mon, 23 Jan 2017 14:18:18 +0100<br>
> From: "M.-A. Lemburg" <<a href="mailto:mal@egenix.com">mal@egenix.com</a>><br>
> To: "Soni L." <<a href="mailto:fakedme%2Bpy@gmail.com">fakedme+py@gmail.com</a>>, <a href="mailto:python-ideas@python.org">python-ideas@python.org</a><br>
> Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator<br>
> Message-ID: <<a href="mailto:0654a27e-7200-c468-d4eb-17bef13b61d2@egenix.com">0654a27e-7200-c468-d4eb-<wbr>17bef13b61d2@egenix.com</a>><br>
> Content-Type: text/plain; charset=windows-1252<br>
><br>
> On 23.01.2017 14:05, Soni L. wrote:<br>
> ><br>
> ><br>
> > On 23/01/17 09:45 AM, Serhiy Storchaka wrote:<br>
> >> On 23.01.17 01:30, Soni L. wrote:<br>
> >>> On 22/01/17 08:54 PM, Serhiy Storchaka wrote:<br>
> >>>> On 23.01.17 00:45, Soni L. wrote:<br>
> >>>>> I've been thinking of an Immutable Builder pattern and an operator<br>
> >>>>> to go<br>
> >>>>> with it. Since the builder would be immutable, this wouldn't work:<br>
> >>>>><br>
> >>>>> long_name = mkbuilder()<br>
> >>>>> long_name.seta(a)<br>
> >>>>> long_name.setb(b)<br>
> >>>>> y = long_name.build()<br>
> >>>><br>
> >>>> I think the more pythonic way is:<br>
> >>>><br>
> >>>> y = build(a=a, b=b)<br>
> >>>><br>
> >>>> A Builder pattern is less used in Python due to the support of keyword<br>
> >>>> arguments.<br>
> >>><br>
> >>> I guess you could do something like this, for an IRC bot builder:<br>
> >>><br>
> >>> fnircbotbuilder = mkircbotbuilder(network="<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc.<wbr>freenode.net</a>",<br>
> port=6697,<br>
> >>> ssl=true)<br>
> >>> mainbot = mkircbotbuilder(parent=<wbr>fnircbotbuilder, # ???<br>
> >>> channels=["#bots"]).build()<br>
> >>> fndccbotbuilder = mkircbotbuilder(parent=<wbr>fnircbotbuilder, dcc=true,<br>
> >>> channeldcc=true)<br>
> >>> dccbot = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> >>> channels=["#ctcp-s"]).build()<br>
> >>> otherircbotbuilder = mkircbotbuilder(parent=<wbr>fndccbotbuilder,<br>
> >>> network="<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>") # because we want this whole network<br>
> >>> otherbot = mkircbotbuilder(parent=<wbr>otherircbotbuilder,<br>
> >>> channels=["#programming"]).<wbr>build() # to use DCC and channel DCC<br>
> >>><br>
> >>> But this would be cleaner:<br>
> >>><br>
> >>> botbuilder =<br>
> >>> mkircbotbuilder().network("<a href="http://irc.freenode.net" rel="noreferrer" target="_blank">irc<wbr>.freenode.net</a>").port(6697).<wbr>ssl(true)<br>
> >>> mainbot = botbuilder.channels(["#bots"])<wbr>.build()<br>
> >>> botbuilder .= dcc(true).channeldcc(true)<br>
> >>> dccbot = botbuilder.channels(["#ctcp-s"<wbr>]).build()<br>
> >>> botbuilder .= network("<a href="http://irc.subluminal.net" rel="noreferrer" target="_blank">irc.subluminal.net</a>")<br>
> >>> otherbot = botbuilder.channels(["#<wbr>programming"]).build()<br>
> >><br>
> >> In Python you can save common options in a dict and pass them as<br>
> >> var-keyword argument. Or use functools.partial. In any case you don't<br>
> >> need a builder class with the build method and a number of configuring<br>
> >> methods. It can be just a function with optional keyword parameters.<br>
> >><br>
> >> A Builder pattern is often used in languages that don't support<br>
> >> passing arguments by keyword and partial functions. Python rarely<br>
> >> needs the purposed class implementing a Builder pattern. Actually a<br>
> >> Builder pattern is built-in in the language as a part of syntax.<br>
> >><br>
> > Yeah but the dotequals operator has many other benefits:<br>
> ><br>
> > long_name .= __call__ # cast to callable<br>
> > long_name .= wrapped # unwrap<br>
> > etc<br>
> ><br>
> > And it also looks neat.<br>
><br>
> I don't see this an being a particular intuitive way of writing<br>
> such rather uncommon constructs.<br>
><br>
> The syntax is not clear (what if you have an expression on the RHS)<br>
> and it doesn't save you much in writing (if long_name is too long<br>
> simply rebind it under a shorter name for the purpose of the code<br>
> block).<br>
><br>
> Also note that rebinding different objects to the same name<br>
> in the same block is often poor style and can easily lead to<br>
> hard to track bugs.<br>
><br>
> --<br>
> Marc-Andre Lemburg<br>
> eGenix.com<br>
><br>
> Professional Python Services directly from the Experts (#1, Jan 23 2017)<br>
> >>> Python Projects, Coaching and Consulting ... <a href="http://www.egenix.com/" rel="noreferrer" target="_blank">http://www.egenix.com/</a><br>
> >>> Python Database Interfaces ... <a href="http://products.egenix.com/" rel="noreferrer" target="_blank">http://products.egenix.com/</a><br>
> >>> Plone/Zope Database Interfaces ... <a href="http://zope.egenix.com/" rel="noreferrer" target="_blank">http://zope.egenix.com/</a><br>
> ______________________________<wbr>______________________________<wbr>____________<br>
><br>
> ::: We implement business ideas - efficiently in both time and costs :::<br>
><br>
> eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48<br>
> D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg<br>
> Registered at Amtsgericht Duesseldorf: HRB 46611<br>
> <a href="http://www.egenix.com/company/contact/" rel="noreferrer" target="_blank">http://www.egenix.com/company/<wbr>contact/</a><br>
> <a href="http://www.malemburg.com/" rel="noreferrer" target="_blank">http://www.malemburg.com/</a><br>
><br>
><br>
><br>
> ------------------------------<br>
><br>
> Subject: Digest Footer<br>
><br>
> ______________________________<wbr>_________________<br>
> Python-ideas mailing list<br>
> <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
><br>
><br>
> ------------------------------<br>
><br>
> End of Python-ideas Digest, Vol 122, Issue 81<br>
> ******************************<wbr>***************<br>
><br>
-------------- next part --------------<br>
An HTML attachment was scrubbed...<br>
URL: <<a href="http://mail.python.org/pipermail/python-ideas/attachments/20170123/d9a848aa/attachment.html" rel="noreferrer" target="_blank">http://mail.python.org/<wbr>pipermail/python-ideas/<wbr>attachments/20170123/d9a848aa/<wbr>attachment.html</a>><br>
<br>
------------------------------<br>
<br>
Subject: Digest Footer<br>
<br>
______________________________<wbr>_________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
<br>
<br>
------------------------------<br>
<br>
End of Python-ideas Digest, Vol 122, Issue 82<br>
******************************<wbr>***************<br>
</blockquote></div>