[Python-ideas] Method chaining notation

Haoyi Li haoyi.sg at gmail.com
Sat Feb 22 02:33:02 CET 2014


> This can be done with an external wrapper, so it might be possible to
do this with MacroPy. It absolutely must be a compact notation,
though.

Something like:

merged = c[ my_dict.update(dict_a).update(dict_b) ]

Desugaring into

# top-level somewhere elsedef fresh_name(x, *args):
    y = x
    for op, a, kw in args:
        y = getattr(y, op)(*a, **kw)
        y = x if y is None else y
    return y
merged = fresh_name(my_dict, ("update", [dict_a], {}), ("update", [dict_b], {}))

could be doable pretty easily, and is flexible enough to make old-school
chaining work while also letting things that return None do the right
thing. If you don't want to use macros, an alternative could be doing
something like:

chain(my_dict).update(dict_a).update(dict_b).get

Using a wrapper as Steven mentioned.



On Fri, Feb 21, 2014 at 5:13 PM, Steven D'Aprano <steve at pearwood.info>wrote:

> On Sat, Feb 22, 2014 at 04:30:03AM +1100, Chris Angelico wrote:
> > Yeah, I'm insane, opening another theory while I'm busily championing
> > a PEP.
>
> Completely raving bonkers :-)
>
> > In Python, as in most languages, method chaining requires the method
> > to return its own object.
> [...]
>
> Rather than add syntactic support for this, I'd prefer a wrapper in the
> standard library. Syntax implies to me that chaining operators is, in
> some sense, a preferred idiom of the language, and although method
> chaining is sometimes useful, I don't think that it ought to be
> preferred. There's a difference between "Python supports this, use this
> syntax" and "You can do this in Python, import this library and call
> this function to make it happen".
>
>
> [...]
> > So here's the proposal. Introduce a new operator to Python, just like
> > the dot operator but behaving differently when it returns a bound
> > method. We can possibly use ->, or maybe create a new operator that
> > currently makes no sense, like .. or .> or something. Its semantics
> > would be:
> >
> > 1) Look up the attribute following it on the object, exactly as per
> > the current . operator
> > 2) If the result is not a function, return it, exactly as per current.
> > 3) If it is a function, though, return a wrapper which, when called,
> > calls the inner function and then returns self.
>
> When you say "a function", do you actually mean a function? What about
> other callables, such as methods (instance, class or static) or types?
> How does this interact with the descriptor protocol?
>
>
> > This can be done with an external wrapper, so it might be possible to
> > do this with MacroPy. It absolutely must be a compact notation,
> > though.
>
> Here's an alternative: add a `chained` wrapper to, oh, let's say
> functools (I don't think it needs to be a built-in). In my hierarchy of
> language preferredness, this suggests that while Python *supports*
> method chaining, it isn't *preferred*. (If it were preferred, it would
> happen by default, or there would be syntax for it.) If you want to
> chain methods, you can, but it's a slightly unusual thing to do, and the
> fact that you have to import a module and call a wrapper class should be
> sufficient discouragement for casual (ab)use.
>
> Inspired by the Ruby "tap" method, I wrote this proof-of-concept last
> year:
>
> https://mail.python.org/pipermail/python-list/2013-November/660892.html
>
> http://code.activestate.com/recipes/578770-method-chaining/
>
> Of course, if the class author wants to support method chaining, they
> can always write the methods to return self :-)
>
>
> --
> Steven
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140221/0739d9f6/attachment-0001.html>


More information about the Python-ideas mailing list