omghax said it right - just look at the wealth of Linux/Unix command-line tools, and you'll see a great example of this concept.
I see the text tools of Linux as software Legos. Focused, single-purpose tools (which may be yet be internally complex) which are useful individually, and yet may be easily combined to solve many complicated problems.
One thing these software Legos share with the plastic kind is their individual focus on a particular problem domain. None of these tools can do more than a small handfull of related functions. grep by itself isn't any good at anything at all, other than finding lines that match the given regular expression. ls is useless except for listing files on the hard disk, with only the most basic of filename filtering. However, together, they provide a great filesystem query system. Their simplicity makes them easy to write, easy to maintain, and easy to comprehend and remember - crucial if it is to be of any utility in an environment based on combinatorial interaction.
The OTHER thing that these tools share with Legos - and this CAN NOT be overlooked - is the open and SIMPLE manner in which they can interact. All Lego bricks have plastic dots on the top, and allow those same plastic dots to be snapped into the bottom. Every Lego brick, regardless of shape, color, or obvious intended use (I really liked those clear cockpit pieces) shared this interface. It allowed me to build buildings, bulldozers, and airplanes with those simple bricks. Cockpit pieces and wing pieces and ordinary 2x4 bricks could be snapped together to make any shape my imagination produced.
And what's funny was, the more exotic the part, the fewer uses I could find for it. Slanted parts were good for decorating my masterpieces; they made the blocks look less blocky. Cockpit parts were great for cockpits, and the occasional window...but not much else. But regardless of whether it was an ordinary building or a fighter with forward-swept wings (still sitting in my parents' house), my most-used parts were the rectangular bricks. Simple, boring, but infinitely useful.
The Linux Model
Command-line tools in Linux all have these interfaces:
Command-line arguments allow you to specify details of how the tool is to behamve - in human-readable text. And STDIN and STDOUT resulted in I/O that was individually useful, yet (with shell support for piping) infinitely combinable.
- Command-line arguments
- File streams, always including STDIN and STDOUT
I'm not saying that "everything's a file" is necessarily the best way to do this. I'm just saying that it is one way to do this, and it's popular, and it works. Windows, while supporting this mechanism, seems more largely built on the 'plugin' model (drivers vs. services vs. applications vs. shell extensions vs...). This, too, works, but there is very little reuse of programs in that environment. A piece of code is written to do that one thing, and it does only that thing, and nothing else. Combinatorial interaction is almost unheard-of in Windows.
GUI applications are great for several reasons: Learn-at-a-Glance GUI apps can be much easier to learn than command-line apps, simply because their options are presented instantly and in an organized fashion.
Idiot-proofing The interface layer of graphical applications can be written to disallow ill-advised actions, and guide the user in the best direction.
Optimal Display of Arbitrary Data GUI apps have the advantage of being able to display any kind of data with the most optimum representation - tables, formatted text, pictures, and 3D scenes can all be displayed and edited intuitively
The clipboard concept helps the situtation, but doesn't completely solve it:
I think we're stuck with the data format issue. MSPaint and Notepad will never work together as smoothly as grep and ls. But I think there are some things we can do:
- Distinct Apps Apps are still annoyingly distinct, needing to be opened and closed separately
- The Event ModelThe event-driven programming model (a huge advance) complicates matters, in that GUI apps stay open, waiting on user commands to take action.
- Arbitrary Data Formats And there's still the huge issue of data type and format - it's not easy to paste text into MSPaint, and impossible to paste an image into Notepad.
Vive le Piping STDIN and STDOUT should be revived, clipboard-style. It should be possible to copy all active data to the clipboard, send it to a newly-started app, wait for that app to close, then process the results, also stored in the clipboard (it might be a good idea to have a second, hidden clipboard for this purpose). Spell-checkers, grammar-checkers, Find and Replace, File Open, and File Close could all work that way. Graphics filters, video and audio effects, email filtering, even >gasp< script languages like Perl, Python, and Ruby.
Simplify, Simplify, Simplify. GUI applications could then focus on a small problem, just like command-line utilities. MDI (multiple-document interface) should go away; having multiple documents open and limiting programs to one running instance would horribly complicate things.
Unleash the User I'm not proposing that the "Spell-check" button launch a new app. I'm proposing a new "system" button that sits up by the Close and Minimize buttons. It would bring up a list of GUI utilities that accept the active data's format. You click the app, launching it. Then the new app is in control - asking you what to search for, how to handle a misspelled word, the particular Ruby script you want to run.
All the developer has to do is make sure the system knows what data types his app will accept and generate (/etc/appdata/, anyone?). Instantly his Notepad clone has spell-checking, find, replace, email, publish to web, and any other features already installed on the client's machine. And if your word processor doesn't have the feature you want, you can download the appropriate utility. You want edge-detect in Paint? Download it! Upgrade it! You want a spam filter for your email client? Buy one! Write it in Ruby!
Let the flames begin...