On Sun, May 24, 2020 at 11:21 AM Steven D'Aprano <steve@pearwood.info> wrote:
> But how would you go about getting a .__matmul__ attribute onto all
> functions. For ones you write yourselves, you could decorate them at
> definition. What about all the other functions though.

As a functional programming fan, you might not know about this, but we
object oriented programming people have this concept called
"inheritance" where we would add the attribute to FunctionType once, and
just like magic every function would support it!

I think I heard of that inheritance thing somewhere! :-)

My thought is really that there's no way we're going to get .__matmul__ added (with the meaning "compose") to FunctionType.  So I was thinking about what one could do with a separate module.  I.e. something that could live on PyPI... before, perhaps someday, being added to standard library.

Is there an evil way to monkey patch FunctionType? I.e. without actually recompiling a fork of the interpreter.  Alex' forbiddenfruit.curse is pretty cool looking.  But it does require explicitly cursing each individual function that might be composed.

Alex Hall:
But seriously, I don't see that much point to this idea. It's just slightly more concise while not being particularly readable or beginner friendly.

sorted(paths, key=len @ str)
sorted(paths, key=lambda p: len(str(p)))

I think once you compose three or more functions, lambda starts to look pretty bad.  This is only slightly mitigated by one of those proposals for "a more concise lambda" that occur intermittently. And if you actually save a composed function under a meaningful name for later use, that much more so.  Of course, I'm really not all that bothered by `my_op = compose(fun1, fun2, fun3, fun4)`.  The @ might be cool, but writing my own HoF compose() isn't hard.

I've been playing more lately with R Tidyverse.  It's pipe with currying of first argument is actually really nice.  The pipe operator is god-awful ugly.  But other than that it works nicely.  For example:

iris %>%
  group_by(Species) %>%
  summarize_if(is.numeric, mean) %>%
  ungroup() %>%
  gather(measure, value, -Species) %>%
  arrange(value)

It's not abstract composition since it always starts with a concrete object the several operations work on.  But it is some of the same feel.

--
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.