[Python-ideas] How do you think about these language extensions?

David Mertz mertz at gnosis.cx
Sat Aug 19 12:05:36 EDT 2017


You are right, of course. Mine does the order wrong. But an 'rcompose()' or
'pipe()' or 'funchain()' is easy enough to put in the right order.

On Aug 19, 2017 3:44 AM, "Steven D'Aprano" <steve at pearwood.info> wrote:

> On Fri, Aug 18, 2017 at 10:33:40PM -0700, David Mertz wrote:
>
> > This is pretty easy to write without any syntax changes, just using a
> > higher-order function `compose()` (possible implementation at foot).
> > Again, I'll assume auto-currying like the map/filter versions of those
> > functions in toolz, as Steven does:
> [...]
>
> > result = compose(map(str.strip),
> >                  filter(lambda s: not startswith('#'),
> >                  sorted,
> >                  collapse,
> >                  extract_dates,
> >                  map(date_to_seconds),
> >                  min
> >                  )(myfile.readlines())
>
> A ~~slight~~ major nit: given the implementation of compose you quote
> below, this applies the functions in the wrong order. min() is called
> first, and map(str.strip) last.
>
> But apart from being completely wrong *wink* that's not too bad :-)
>
> Now we start bike-shedding the aethetics of what looks better
> and reads more nicely. Your version is pretty good, except:
>
> 1) The order of function composition is backwards to that normally
> expected (more on this below);
>
> 2) there's that unfortunate call to "compose" which isn't actually part
> of the algorithm, its just scaffolding to make it work;
>
> 3) the data being operated on still at the far end of the chain, instead
> of the start;
>
> 4) and I believe that teaching a chain of function calls is easier than
> teaching higher order function composition. Much easier.
>
>
> The standard mathematical definition of function composition operates
> left to right:
>
> (f∘g∘h)(x) = f(g(h(x))
>
> http://mathworld.wolfram.com/Composition.html
>
> And that's precisely what your implementation does. Given your
> implementation quoted below:
>
> py> def add_one(x): return x + 1
> ...
> py> def double(x): return 2*x
> ...
> py> def take_one(x): return x - 1
> ...
> py>
> py> compose(add_one,
> ...         double,
> ...         take_one)(10)
> 19
> py>
> py> add_one(double(take_one(10)))
> 19
>
> which is the mathematically expected behaviour. But for chaining, we
> want the operations in the opposite order:
>
> 10 -> add_one -> double -> take_one
>
> which is equivalent to:
>
> take_one(double(add_one(10))
>
>
> So to use composition for chaining, we need:
>
>
> - a non-standard implementation of chaining, which operates in the
>   reverse to what mathematicians and functional programmers expect;
>
> - AND remember to use this rcompose() instead of compose()
>
> - stick to the standard compose(), but put the functions in the
>   reverse order to what we want;
>
> - or use the standard compose, but use even more scaffolding to
>   make it work:
>
> result = compose(*reversed(
>                    ( map(str.strip),
>                      filter(lambda s: not startswith('#')),
>                      sorted,
>                      collapse,
>                      extract_dates,
>                      map(date_to_seconds),
>                      min
>                    )))(myfile.readlines())
>
>
> > def compose(*funcs):
> >     """Return a new function s.t.
> >        compose(f,g,...)(x) == f(g(...(x)))
> >     """
> >     def inner(data, funcs=funcs):
> >         result = data
> >         for f in reversed(funcs):
> >             result = f(result)
> >         return result
> >     return inner
>
>
>
> --
> Steve
> _______________________________________________
> 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/20170819/bb48d54c/attachment.html>


More information about the Python-ideas mailing list