> It's impossible to “redesign” shell fundamentals in Unix because it will be incompatible with all other old-style utilies.
This is not true. In fact, despite its many flaws, PowerShell did solve this particular one: any object stream can also be rendered as a string. This is exactly what happens when you just type `ls` into a PowerShell window.
I can completely imagine that a UNIX `ls` implementation would return a stream of objects (not necessarily .NET objects - just some runtime's native object format) that, when called .toString() on, would return exactly the same textual output as common UNIX `ls`. Then, you'd need a way to differentiate between two pipes. Maybe with syntax (i.e. | for string pipes, [] for object pipes, whatever) or maybe through magic ("hey, these two processes both have the capability to pipe objects instead of characters, let's tie them together as objects" somewhere at the shell level). I'm not sure how feasible either are, but I'm sure you can imagine that this problem could be solved. Then, if the shell sees that whichever process accepts the output of `ls` doesn't understand objects, just text, then it calls `.toString` on every object and renders that to oldschool character stdout.
This is not true. In fact, despite its many flaws, PowerShell did solve this particular one: any object stream can also be rendered as a string. This is exactly what happens when you just type `ls` into a PowerShell window.
I can completely imagine that a UNIX `ls` implementation would return a stream of objects (not necessarily .NET objects - just some runtime's native object format) that, when called .toString() on, would return exactly the same textual output as common UNIX `ls`. Then, you'd need a way to differentiate between two pipes. Maybe with syntax (i.e. | for string pipes, [] for object pipes, whatever) or maybe through magic ("hey, these two processes both have the capability to pipe objects instead of characters, let's tie them together as objects" somewhere at the shell level). I'm not sure how feasible either are, but I'm sure you can imagine that this problem could be solved. Then, if the shell sees that whichever process accepts the output of `ls` doesn't understand objects, just text, then it calls `.toString` on every object and renders that to oldschool character stdout.