(((x)f)g)h
So I can see exactly the order in which things happen, from left to right.
As opposed to: f(g(h(x)))
where I have to read backwards. (((x)f)g)h
So I can see exactly the order in which things happen, from left to right.
As opposed to: f(g(h(x)))
where I have to read backwards. x
|> f
|> g
|> h
It's nice because it just puts whatever's on the left of the operator in as the last argument. So it also works for functions with an arity of more than one.So if it were something like
h(z, g(y, f(x))
you can write it as x
|> f
|> g y
|> h z
It works really nicely for data munging code: my_data
|> filter (x => x > 37)
|> select (x => x * 2)
|> sum
but unlike doing it with method calls in object oriented code, inserting a new function into the chain doesn't involve modifying a class or or mucking around with more complex language features like extension methods and traits. (h . g . f) x
Or for LtR, with Control.Category (f >>> g >>> h) x
Could combine with the forward pipe for x |> (f >>> g >>> h)since the order in which things happen is "h first, then g, then f"
So is this better too
$ less | find / -type f -perm /6000 -ls
than ? $ find / -type f -perm /6000 -ls | less
Just because shell actually starts executables right to left when using pipes.
Reason to this behaviour is because it can fail early if there is problem constructing pipe first and not spend lot of time something finding later that some pipe components can't start and receive data properly.ps. I'm fine with current notation and would not like change it.
f3(f2(f1(some data)))
it would be nice to write some data |> f1 |> f2 |> f3
javascript has proposals for pipe operators because as soon as the simple .map /.filter/.reduce APIs don't suffice (ie. as soon as Promise.all is needed) the f3(f2(f1(data))) mess starts.R.pipe(f1,f2,f3)()
As to more serious programming languages, Erlang, F#, Haskell have forms of a "pipe" operator, roughly
[1 2 3] |> sum |> print
For it to work properly, functions should be either functions of one argument, or support currying.But the original algebra functions, as introduced by Leibniz in 17th century, were, of course, pure functions, more like properties than procedures. So cos(x), aka cos x, is just a formalized shorthand for "cosine of x", so it preserved the order of words typical for Germanic and Romance languages. Maybe if functions were introduced by the Japanese, we would have the reverse order, kind of x の cos.
f(g(h(x))) as x.h().g().f() or even x.h.g.f (parenthesis are optional).
When you're calling a function, you're putting some things into the function... You have to get the things first before you can put them in...
Why didn't it evolve like that in the first place? Is it a byproduct of mathematical notation? If so, I wonder why mathematical notation evolved that way in the first place...
It did, just in Arabic.
But you can also define a "thread" operator easily for doing subsequent function calls. ala `threaded x { f; g; h }`
u v x y
f g
h
This is h(f(u,v), g(x,y)). │u│v│x│y
├─┴─├─┴─
│f │g
├───┴─
│h
└─
With >2 inputs and longer names. │uh│v │xizzy│yeez
├──┴─ ├─────┴────
│fooey │gar
├──────┴───
│hello
└─────
The associative property. (a+b)+c=a+(b+c)=a+b+c
│a│b │b│c
├─┴─ ├─┴─
│+ │c│a│+ │a│b│c
├───┴─├─┴─ ├─┴─┴─
│+ │+ │+
├─────┴─────┴─
│=
└─
The quadratic formula. (-b±sqrt(b^2-4*a*c))/(2*a)
│b│2│4│a│c
├─┴─├─┴─┴─
│^ │*
├───┴─
│b│-
├─├─
│-│sqrt│2│a
├─┴────├─┴─
│± │*
├──────┴─
│/
└─
Obviously, it takes way more space and time to draw. Tell me if you like it!It's more natural to write
x.h().g().f() var chain = x=>f=>f?chain(f(x)):x;
chain(x)(h)(g)(f)();
if you need to partly curry to free first argument var _ = (f,...y)=>x=>f(x,...y);
var sum = (x,y)=>x+y;
chain(1)(_(sum,1))()
if you want whole pipeline var $ = (x,...f)=>f.reduce((x,f)=>f(x),x);
$(1,_(sum,1));
which gives fun ability to extract function without input param var sum1 = _($,_(sum,1));
sum1(1);
... which in turn is just having fun with point-free JS foo.bar(x)
The `foo.bar` field has to be retrieved before the function can be called. It does not evaluate `x` first. That is observable with JS proxies, or you can test with code like this: foo()(bar())But my point is that the reference to the function you are calling is actually its own term that needs to be considered in the order of evaluation.
You can also use the IIFE (immediately invoked function expression) pattern that is/was common in JS as an example:
(function() {
// ...
})();
You can use any valid expression in place of a function name, including anything that causes observable side effects.