This article introduces concatenative langauges, but it doesn't explain why they matter.
In my work, I found that the lack of syntactic marking for arguments of function calls is a devastating drawback. Coming back to my own function definitions a week after writing them, I spent minutes unpuzzling the code. I could use every trick and write the function in the most elegant way, using combinators in the style of Factor, and that made it worse. But writing it out with local bindings also didn't help. As soon as you write a nested expression, you start to lose the sense of which values are being passed where.
gcd n1 n2 n2 0 = if n1 else n2 n1 n2 mod gcd
gcd zero if else "mod" plus swap gcd
factorial 1 interval product
I was designing a Forth-like functional language with generic functions, and for a long time I felt that the lack of markings didn't matter. I thought that one could understand the code "well enough" without knowing exactly where the arguments were going. There is something to this argument, and there's a lot we can do to make code say what it does. But sometimes the author just had to implement something, and technicalities arose, and when you go to read it, the code doesn't "read" and you have to bring your own intelligence to figure out what it does -- it won't tell you. In these cases, explicit argument marking is indispensable.
In Forth-like languages, simple things are wonderful and elegant. There is no other shorter way to write than point-free. And, writing with combinators is satisfying, and it can make the "essence of the function" more evident. But unless you severely constrain your style to ultra short definitions, avoid nested expressions, and use local variables profusely, you're constructing puzzles for yourself.
It's almost like the concatenative style is too optimal. You have to back up a step in beauty in order to get a practical tool.