Civet
Civet copied to clipboard
Proper compose operator
I've implemented this operator before:
operator o looser(??) <T < ???[], U, V>(lhs: (arg: U) => V, rhs: (...args: T) => U): (...args: T) => V
(...args) => lhs rhs ...args
However, implementing this in userspace has a few drawbacks:
- Because this is an actual JS function at runtime, there is a minor performance and code size hit. (Somehow, terser is smart enough to inline this, so in practice it doesn't matter.)
- Unlike with
|>, you can lose thethisvalue of the arguments. So instead offoo.bar o baz.qux, you have to sayfoo@bar o baz@qux.
So, I propose that a similar operator be introduced at the language level into Civet. (It doesn't have to be o -- I just called it that because the mathematical symbol for composition is a circle.) foo o bar becomes (...args) => foo(bar(...args)), with the same precedence as |>. When chained, the arguments are only spread once: foo o bar o baz becomes (...args) => foo(bar(baz(...args))).
This is left-associative with |> and ||>, so foo o bar |> baz is baz((...args) => foo(bar(...args))), and foo |> bar o baz would be (...args) => bar(foo)(baz(...args)).
Related to https://github.com/DanielXMoore/Civet/discussions/1081