Good question. I'm not an expert in functional programming but it's changed my mindset.
Imperative / functional languages are equally powerful, but are they equally expressive? There's a reason I wrote the above in a shell script vs. an OO-language (or C): shell scripting captures my intent with minimal overhead, with the right primitives built-in.
OO-languages force you to define classes, methods, type input parameters, etc. up front. So if you know you just want that exact workflow then you can model it.
What if I want to customize the sort routine? Well, I guess I can define a sorting interface and take that as an argument.
And what if I want a more flexible data structure? (With unix it's all text, but why not a hashmap being passed around?). Well, I can define a generic "list" class with an infinite number of members, and all the operations change this list.
But now we've gotten away from OO programming (saying data is of type "List" is not saying much at all).
We're basically trying to recreate functional programming ideas:
* Simple, flexible, built-in data structures (list of lists)
* Pass around functions at runtime, as you please (no interface to define, instantiate an object of that interface, and pass in)
* Composable functions (at runtime, decide that function Z is really F(G(x)))
It's not that the operations aren't possible, but OO languages seem to lead you down a specification-first path, usually customized to a problem domain.
You can "get around" this by using design patterns like Strategy, but again, you're recreating functional ideas in another language. Not that it's impossible, but it's not quite suited for the problem domain (like doing text processing in C vs. using perl... yes, you can find a regex lib, and a better string class, but why not use a language with it built in?).
Hope this helps -- different languages help you think differently. I've used C# a lot and really love the mix of functional and imperative styles in the latest versions (3.5). Joel had a good post (http://www.joelonsoftware.com/items/2006/08/01.html) on this regarding map/reduce: it's not that it's "impossible" in OO languages, but you don't instinctively think about ideas like "passing around a function and apply it to data".
Your example is way different. You're operating on objects instead of return values. Rewriting what you gave:
using namespace UnixUtilities;
No object necessary. No storage necessary. For your example to work the object needs to store the result of each method call in some member variable. Why is that a bad thing? Because it's harder to reason about member variables (that could change) than return values (which will always be the same if there is no state).
The OO example works off of return values, and the next .method() is on the return value of the previous call. It's almost totally isomorphic to your example (calling a function with the output of another), and isn't even really very OO in and of itself.
Ah, of course. That's what I get for commenting when I'm tired. The only comment that I would make is that the dot notation is very OO, indicating the method on the right is a member of the class of the object on the left. The 'using namespace' in my code was used to indicate the methods I called were static, thereby decoupling them from a particular object.
You're right, the location the function/method lives is slightly different. When I said it wasn't really OO, it is because there's no data encapsulation going on. Just running methods on the output of another method. The line of code could belong in an OO system, but is not in itself OO.