Pleasing to see and somehow elegant. I believe .= is a good idea. On Jan 23, 2017 14:18, <python-ideas-requ...@python.org> wrote:
> Send Python-ideas mailing list submissions to > python-ideas@python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/python-ideas > or, via email, send a message with subject or body 'help' to > python-ideas-requ...@python.org > > You can reach the person managing the list at > python-ideas-ow...@python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Python-ideas digest..." > > > Today's Topics: > > 1. Re: "Immutable Builder" Pattern and Operator (Cory Benfield) > 2. Re: "Immutable Builder" Pattern and Operator (Paul Moore) > 3. Re: "Immutable Builder" Pattern and Operator (Serhiy Storchaka) > 4. Re: "Immutable Builder" Pattern and Operator (Soni L.) > 5. Re: "Immutable Builder" Pattern and Operator (M.-A. Lemburg) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Mon, 23 Jan 2017 09:32:02 +0000 > From: Cory Benfield <c...@lukasa.co.uk> > To: "Soni L." <fakedme...@gmail.com> > Cc: python-ideas@python.org > Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator > Message-ID: <8671ebca-148f-41c8-a592-46ef653b9...@lukasa.co.uk> > Content-Type: text/plain; charset="utf-8" > > > > On 22 Jan 2017, at 22:45, Soni L. <fakedme...@gmail.com> wrote: > > > > > > This pattern is present in the cryptography module already with things > like their x509.CertificateBuilder: https://cryptography.io/en/ > latest/x509/reference/#cryptography.x509.CertificateBuilder < > https://cryptography.io/en/latest/x509/reference/#cryptography.x509. > CertificateBuilder>. > > My 2c, but I find that code perfectly readable and legible. I don?t think > a dot-equals operator would be needed. > > Cory > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: <http://mail.python.org/pipermail/python-ideas/ > attachments/20170123/c4e7d09f/attachment-0001.html> > > ------------------------------ > > Message: 2 > Date: Mon, 23 Jan 2017 09:54:55 +0000 > From: Paul Moore <p.f.mo...@gmail.com> > To: "Soni L." <fakedme...@gmail.com> > Cc: Python-Ideas <python-ideas@python.org> > Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator > Message-ID: > <CACac1F9CcDEyNuvGBSNSpm+U0=VQNaN9Yd-Mgj+q_Uk16gxGfQ@mail. > gmail.com> > Content-Type: text/plain; charset=UTF-8 > > On 22 January 2017 at 22:45, Soni L. <fakedme...@gmail.com> wrote: > > I've been thinking of an Immutable Builder pattern and an operator to go > > with it. Since the builder would be immutable, this wouldn't work: > > > > long_name = mkbuilder() > > long_name.seta(a) > > long_name.setb(b) > > y = long_name.build() > > > > Instead, you'd need something more like this: > > > > long_name = mkbuilder() > > long_name = long_name.seta(a) > > long_name = long_name.setb(b) > > y = long_name.build() > > > > Or we could add an operator to simplify it: > > > > long_name = mkbuilder() > > long_name .= seta(a) > > long_name .= setb(b) > > y = long_name.build() > > > > (Yes, I'm aware you can x = mkbuilder().seta(a).setb(b), then y = > x.build(). > > But that doesn't work if you wanna "fork" the builder. Some builders, > like a > > builder for network connections of some sort, would work best if they > were > > immutable/forkable.) > > I don't think the .= operator adds enough to be worth it. If the > problem you see is the duplication of long_name in those lines (it's > difficult to be sure without a real example) then you can use a > temporary: > > b = mkbuilder() > b = b.seta(a) > b = b.setb(b) > long_name = b > y = long_name.build() > > For your real example: > > On 22 January 2017 at 23:30, Soni L. <fakedme...@gmail.com> wrote: > > fnircbotbuilder = mkircbotbuilder(network="irc.freenode.net", port=6697, > > ssl=true) > > mainbot = mkircbotbuilder(parent=fnircbotbuilder, # ??? > > channels=["#bots"]).build() > > fndccbotbuilder = mkircbotbuilder(parent=fnircbotbuilder, dcc=true, > > channeldcc=true) > > dccbot = mkircbotbuilder(parent=fndccbotbuilder, > > channels=["#ctcp-s"]).build() > > otherircbotbuilder = mkircbotbuilder(parent=fndccbotbuilder, > > network="irc.subluminal.net") # because we want this whole network > > otherbot = mkircbotbuilder(parent=otherircbotbuilder, > > channels=["#programming"]).build() # to use DCC and channel DCC > > > > But this would be cleaner: > > > > botbuilder = > > mkircbotbuilder().network("irc.freenode.net").port(6697).ssl(true) > > mainbot = botbuilder.channels(["#bots"]).build() > > botbuilder .= dcc(true).channeldcc(true) > > dccbot = botbuilder.channels(["#ctcp-s"]).build() > > botbuilder .= network("irc.subluminal.net") > > otherbot = botbuilder.channels(["#programming"]).build() > > I don't find the second example appreciably cleaner than the first. > But a bit of reformatting looks better to me: > > # First create builders for the bots > fnircbotbuilder = mkircbotbuilder( > network="irc.freenode.net", > port=6697, > ssl=true) > fndccbotbuilder = mkircbotbuilder( > parent=fnircbotbuilder, > dcc=true, > channeldcc=true) > otherircbotbuilder = mkircbotbuilder( > parent=fndccbotbuilder, > network="irc.subluminal.net") > > # Now create the actual bots > mainbot = mkircbotbuilder( > parent=fnircbotbuilder, > channels=["#bots"]).build() > dccbot = mkircbotbuilder( > parent=fndccbotbuilder, > channels=["#ctcp-s"]).build() > otherbot = mkircbotbuilder( > parent=otherircbotbuilder, > channels=["#programming"]).build() > > And some API redesign (make the builders classes, and the parent > relationship becomes subclassing, and maybe make channels an argument > to build() so that you don't need fresh builders for each of the > actual bots, and you don't even need the "builder" in the name at this > point) makes the whole thing look far cleaner (to me, at least): > > class FNIRCBot(IRCBot): > network="irc.freenode.net" > port=6697 > ssl=True > class FNDCCBot(FNIRCBot): > dcc=True > channeldcc=True > class OtherIRCBot(IRCBot): > network="irc.subluminal.net" > > mainbot = FNIRCBot(channels=["#bots"]) > dccbot = FNDCCBot(channels=["#ctcp-s"]) > otherbot = OtherIRCBot(channels=["#programming"]) > > Paul > > > ------------------------------ > > Message: 3 > Date: Mon, 23 Jan 2017 13:45:18 +0200 > From: Serhiy Storchaka <storch...@gmail.com> > To: python-ideas@python.org > Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator > Message-ID: <o64qc9$k3q$1...@blaine.gmane.org> > Content-Type: text/plain; charset=windows-1252; format=flowed > > On 23.01.17 01:30, Soni L. wrote: > > On 22/01/17 08:54 PM, Serhiy Storchaka wrote: > >> On 23.01.17 00:45, Soni L. wrote: > >>> I've been thinking of an Immutable Builder pattern and an operator to > go > >>> with it. Since the builder would be immutable, this wouldn't work: > >>> > >>> long_name = mkbuilder() > >>> long_name.seta(a) > >>> long_name.setb(b) > >>> y = long_name.build() > >> > >> I think the more pythonic way is: > >> > >> y = build(a=a, b=b) > >> > >> A Builder pattern is less used in Python due to the support of keyword > >> arguments. > > > > I guess you could do something like this, for an IRC bot builder: > > > > fnircbotbuilder = mkircbotbuilder(network="irc.freenode.net", port=6697, > > ssl=true) > > mainbot = mkircbotbuilder(parent=fnircbotbuilder, # ??? > > channels=["#bots"]).build() > > fndccbotbuilder = mkircbotbuilder(parent=fnircbotbuilder, dcc=true, > > channeldcc=true) > > dccbot = mkircbotbuilder(parent=fndccbotbuilder, > > channels=["#ctcp-s"]).build() > > otherircbotbuilder = mkircbotbuilder(parent=fndccbotbuilder, > > network="irc.subluminal.net") # because we want this whole network > > otherbot = mkircbotbuilder(parent=otherircbotbuilder, > > channels=["#programming"]).build() # to use DCC and channel DCC > > > > But this would be cleaner: > > > > botbuilder = > > mkircbotbuilder().network("irc.freenode.net").port(6697).ssl(true) > > mainbot = botbuilder.channels(["#bots"]).build() > > botbuilder .= dcc(true).channeldcc(true) > > dccbot = botbuilder.channels(["#ctcp-s"]).build() > > botbuilder .= network("irc.subluminal.net") > > otherbot = botbuilder.channels(["#programming"]).build() > > In Python you can save common options in a dict and pass them as > var-keyword argument. Or use functools.partial. In any case you don't > need a builder class with the build method and a number of configuring > methods. It can be just a function with optional keyword parameters. > > A Builder pattern is often used in languages that don't support passing > arguments by keyword and partial functions. Python rarely needs the > purposed class implementing a Builder pattern. Actually a Builder > pattern is built-in in the language as a part of syntax. > > > > > ------------------------------ > > Message: 4 > Date: Mon, 23 Jan 2017 11:05:12 -0200 > From: "Soni L." <fakedme...@gmail.com> > To: python-ideas@python.org > Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator > Message-ID: <e9f1547f-c5a6-045a-8716-7669a1662...@gmail.com> > Content-Type: text/plain; charset=windows-1252; format=flowed > > > > On 23/01/17 09:45 AM, Serhiy Storchaka wrote: > > On 23.01.17 01:30, Soni L. wrote: > >> On 22/01/17 08:54 PM, Serhiy Storchaka wrote: > >>> On 23.01.17 00:45, Soni L. wrote: > >>>> I've been thinking of an Immutable Builder pattern and an operator > >>>> to go > >>>> with it. Since the builder would be immutable, this wouldn't work: > >>>> > >>>> long_name = mkbuilder() > >>>> long_name.seta(a) > >>>> long_name.setb(b) > >>>> y = long_name.build() > >>> > >>> I think the more pythonic way is: > >>> > >>> y = build(a=a, b=b) > >>> > >>> A Builder pattern is less used in Python due to the support of keyword > >>> arguments. > >> > >> I guess you could do something like this, for an IRC bot builder: > >> > >> fnircbotbuilder = mkircbotbuilder(network="irc.freenode.net", > port=6697, > >> ssl=true) > >> mainbot = mkircbotbuilder(parent=fnircbotbuilder, # ??? > >> channels=["#bots"]).build() > >> fndccbotbuilder = mkircbotbuilder(parent=fnircbotbuilder, dcc=true, > >> channeldcc=true) > >> dccbot = mkircbotbuilder(parent=fndccbotbuilder, > >> channels=["#ctcp-s"]).build() > >> otherircbotbuilder = mkircbotbuilder(parent=fndccbotbuilder, > >> network="irc.subluminal.net") # because we want this whole network > >> otherbot = mkircbotbuilder(parent=otherircbotbuilder, > >> channels=["#programming"]).build() # to use DCC and channel DCC > >> > >> But this would be cleaner: > >> > >> botbuilder = > >> mkircbotbuilder().network("irc.freenode.net").port(6697).ssl(true) > >> mainbot = botbuilder.channels(["#bots"]).build() > >> botbuilder .= dcc(true).channeldcc(true) > >> dccbot = botbuilder.channels(["#ctcp-s"]).build() > >> botbuilder .= network("irc.subluminal.net") > >> otherbot = botbuilder.channels(["#programming"]).build() > > > > In Python you can save common options in a dict and pass them as > > var-keyword argument. Or use functools.partial. In any case you don't > > need a builder class with the build method and a number of configuring > > methods. It can be just a function with optional keyword parameters. > > > > A Builder pattern is often used in languages that don't support > > passing arguments by keyword and partial functions. Python rarely > > needs the purposed class implementing a Builder pattern. Actually a > > Builder pattern is built-in in the language as a part of syntax. > > > Yeah but the dotequals operator has many other benefits: > > long_name .= __call__ # cast to callable > long_name .= wrapped # unwrap > etc > > And it also looks neat. > > > ------------------------------ > > Message: 5 > Date: Mon, 23 Jan 2017 14:18:18 +0100 > From: "M.-A. Lemburg" <m...@egenix.com> > To: "Soni L." <fakedme...@gmail.com>, python-ideas@python.org > Subject: Re: [Python-ideas] "Immutable Builder" Pattern and Operator > Message-ID: <0654a27e-7200-c468-d4eb-17bef13b6...@egenix.com> > Content-Type: text/plain; charset=windows-1252 > > On 23.01.2017 14:05, Soni L. wrote: > > > > > > On 23/01/17 09:45 AM, Serhiy Storchaka wrote: > >> On 23.01.17 01:30, Soni L. wrote: > >>> On 22/01/17 08:54 PM, Serhiy Storchaka wrote: > >>>> On 23.01.17 00:45, Soni L. wrote: > >>>>> I've been thinking of an Immutable Builder pattern and an operator > >>>>> to go > >>>>> with it. Since the builder would be immutable, this wouldn't work: > >>>>> > >>>>> long_name = mkbuilder() > >>>>> long_name.seta(a) > >>>>> long_name.setb(b) > >>>>> y = long_name.build() > >>>> > >>>> I think the more pythonic way is: > >>>> > >>>> y = build(a=a, b=b) > >>>> > >>>> A Builder pattern is less used in Python due to the support of keyword > >>>> arguments. > >>> > >>> I guess you could do something like this, for an IRC bot builder: > >>> > >>> fnircbotbuilder = mkircbotbuilder(network="irc.freenode.net", > port=6697, > >>> ssl=true) > >>> mainbot = mkircbotbuilder(parent=fnircbotbuilder, # ??? > >>> channels=["#bots"]).build() > >>> fndccbotbuilder = mkircbotbuilder(parent=fnircbotbuilder, dcc=true, > >>> channeldcc=true) > >>> dccbot = mkircbotbuilder(parent=fndccbotbuilder, > >>> channels=["#ctcp-s"]).build() > >>> otherircbotbuilder = mkircbotbuilder(parent=fndccbotbuilder, > >>> network="irc.subluminal.net") # because we want this whole network > >>> otherbot = mkircbotbuilder(parent=otherircbotbuilder, > >>> channels=["#programming"]).build() # to use DCC and channel DCC > >>> > >>> But this would be cleaner: > >>> > >>> botbuilder = > >>> mkircbotbuilder().network("irc.freenode.net").port(6697).ssl(true) > >>> mainbot = botbuilder.channels(["#bots"]).build() > >>> botbuilder .= dcc(true).channeldcc(true) > >>> dccbot = botbuilder.channels(["#ctcp-s"]).build() > >>> botbuilder .= network("irc.subluminal.net") > >>> otherbot = botbuilder.channels(["#programming"]).build() > >> > >> In Python you can save common options in a dict and pass them as > >> var-keyword argument. Or use functools.partial. In any case you don't > >> need a builder class with the build method and a number of configuring > >> methods. It can be just a function with optional keyword parameters. > >> > >> A Builder pattern is often used in languages that don't support > >> passing arguments by keyword and partial functions. Python rarely > >> needs the purposed class implementing a Builder pattern. Actually a > >> Builder pattern is built-in in the language as a part of syntax. > >> > > Yeah but the dotequals operator has many other benefits: > > > > long_name .= __call__ # cast to callable > > long_name .= wrapped # unwrap > > etc > > > > And it also looks neat. > > I don't see this an being a particular intuitive way of writing > such rather uncommon constructs. > > The syntax is not clear (what if you have an expression on the RHS) > and it doesn't save you much in writing (if long_name is too long > simply rebind it under a shorter name for the purpose of the code > block). > > Also note that rebinding different objects to the same name > in the same block is often poor style and can easily lead to > hard to track bugs. > > -- > Marc-Andre Lemburg > eGenix.com > > Professional Python Services directly from the Experts (#1, Jan 23 2017) > >>> Python Projects, Coaching and Consulting ... http://www.egenix.com/ > >>> Python Database Interfaces ... http://products.egenix.com/ > >>> Plone/Zope Database Interfaces ... http://zope.egenix.com/ > ________________________________________________________________________ > > ::: We implement business ideas - efficiently in both time and costs ::: > > eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 > D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg > Registered at Amtsgericht Duesseldorf: HRB 46611 > http://www.egenix.com/company/contact/ > http://www.malemburg.com/ > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > > > ------------------------------ > > End of Python-ideas Digest, Vol 122, Issue 81 > ********************************************* >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/