Instead of starting with the command, we should start with an argument. Given a "thing" (that likely exists in your UI), such as a file, a song, a person, a chunk of text, show me the list of commands that accept it as a parameter. You'll quickly discover that a chunk of text can be passed to functions such as "tweet", "copy to clipboard", "create memo", "search on Google", "translate". Congratulations, you just invented the contextual menu, which people have been using for decades.
"Things" are easy to discover; you can see them. Commands that interact with them, are not as easy to discover; you can't see them. Let people touch or name things (with or without a query language), and once they grabbed the instance they care about, show them what can be done with it. It's that simple.
Before:
> /tweet "some random thoughts" // where you had to know 'tweet' existed as a command
After:
> "some random thoughts" -> tweet // where 'tweet' was auto-suggested, along with 'search', 'translate', 'copy', etc.
"What's the command that shows me file system usage again?"
> man -k file system usage
result = 5 pages of matching commands, often poorly formatted, word wrapping oddly, sometimes without even carriage returns between the commands, so it's all one long list. And this is in Unix which has had something like 45 years to clean up this mess.
I don't hold out hope that this sort of interface will ever be presented usefully, and we already have a better system in a GUI.
And heaven help you if you want to find out where all of that data is on the hard drive.
Oh, by the way, it's at:
Apple menu -> About This Mac -> Storage
And don't alt-tab away from it; you can't get back to it using the keyboard. You have to use Mission Control or back through the Apple menu again.
While it works on folders, it just gives you a question mark for the size while it is working out the size of the sub-items on disk with no indication that it's actually going to change that.
So yes, there are alternative methods, but they are no more friendly to discoverability as the Apple Menu method.
The answer lies in your question. A lot of power user (yes, relative but Apple have focused on consumer) functionality is buried in the gui, and every release pushes stuff deeper in to the interface.
It allows you to type queries, and each point offers dropdowns that list valid attributes, operators, values (in case of limited choice of values). I like it.
(system command arguments)
flip -> (system arguments command) curry -> (system arguments) command
# and for the humane touch:
thread (system (completing-read)) (completing-read)
etc etc
Oh, and BTW, GUIs didn't buy ergonomy, sometimes you need to open an application then the data (aka /tweet "bla"), early systems had a simple 1:1 map 'type' 'program' with an 'open-with' intermediate. Then they added 1:N ... One day it will be a tiny Hindley-Milner unifier ;)
echo "My random thoughts" | tweetWhereas English (and other European languages that I know some grammar for) are of the form: Subject Verb
I.e. you're advocating that CLI interfaces should be more like English...
To answer my own objection, > how (or whatever the tool is called), or just the object itself as in the author's example, could display categorized actions, or offer a way to navigate submenus, or it could limit initial output to things that a non-superuser would want to do and offer additional options for superusers to browse more advanced options (or assume they know what other tools exist and use them directly).
For practical reasons it isn't always text, but more importantly (the first bit is a subset of this problem): almost every program has to understand (100%) the output of every other program it has to interact with.
If output were typed our applications could ignore (reliably) the bits they don't care about.
If output were typed we could search by output-type (e.g. diff produces patch-like-output, so don't bother piping to "xargs", but allow "less" (any type of input) or "git apply" (patch-like-input) or "patch" (patch-like-input).
Types could add a huge amount of searchability to CLIs -- and for some reason this isn't appreciated even though we've seen it in a much more limited context such as OOP.
(I think my original inspiration for this line of thinking is Paul Chiusano, and he probably deserves most of the credit, honestly.)
EDIT: Actually, pondering this a little more: All programs should be forced somehow(!) to carry a "source location" for the source of their output. This is such an annoyance in the daily life of a programmer if you perform a chain of commands like "git diff ... | grep FIXME | grep ^+ | ..." just to get a grip on the FIXMEs you've introduced. The output doesn't show line numbers, because... well, for no really good reason, really. It's just that transformation as text meant that we sort of lost that bit.
While I mostly agree with your thesis that types could be great in the shell, I think this particular bit is incorrect in a way that undermines your argument (not, I think, fatally). If a program's output doesn't match up with another program's input, a bit of sed (and maybe some awk) will usually do the trick. And if we added types, that would still be the case - output from one command would have to be the right type to be input to another.
Btw, I didn't mean that types should be the arbiter of "a | b", just that it should guide the search process. Obviously, you should always be allowed to really choose "c" even if the system determined "b". But our UI could be so much efficient if the system chose "b" most of the time.
EDIT: Classic case, btw: "find ... -print0 | xargs -0 ...". Unless we have pervasive and dependent types, how is any formalism going to know that?
Well, it's been sufficient. That doesn't mean we can't improve on it. My point was simply that assigning types doesn't actually change things - it is still the case that every program needs to be able to interpret whatever is generated by every program you want to pipe into it, or you need some kind of translation.
'Classic case, btw: "find ... -print0 | xargs -0 ...". Unless we have pervasive and dependent types, how is any formalism going to know that?'
Dependent types aren't necessary for that. They might be necessary for `find ... $MIGHTBEPRINT0 | xargs $MIGHTBEDASH0`
Edited to add - or wait, you mean the resulting command built by xargs may have a type dependent on the arguments produced by find? That's... messy, yeah.
Yes! Thinking about interactive CLIs... yes.
EDIT: I should add: My main point here is that types would constrict the search space to be reasonable, rather than seeing that "1200 commands are available, do you want to show them all?" prompt. I really think we could be doing much better in this space.
grep -n '^+.*FIXME'
You can also pipe git diff into less or "vim -" to use slash search.Note: on a phone so -n may not be correct.
EDIT: ... and it's actually possibly(!) even worse in the web world where you often have a ridiculous number of levels to your "transformation". Personally, I have never got "bower (source) -> grunt -> ts/(scala.js+closure) -> babel -> es5" (with source maps) to ever work even semi-reliably.
(I know we have too many things in this pipeline, but it's what we have to deal with.)
Basically, however widespread our personal workflows are, there are vastly more workflows we havent't even thought of that are essential to someone else's livelihood, for whom automatic numbering (or whatever) would ruin everything.
As for source maps, yeah, that's got room for improvement.
Hah!
EDIT: I had a really complicated thing here, but decided to delete it... because I don't think anyone understands any of this "computers" thing properly, including me. Hope you understand :).
EDIT#2: Is there a "flowers for you" emoticon?
C# supports extension methods, which are basically static helper methods whose first parameter is the type to which you want to attach the method. For example, I could create a 'ToTitleCase' extension method on type 'string'. Then, given a string instance, I can simply do 'myString.ToTitleCase()'.
One step further would be to add support for multiple parameters. For example, instead of listing all functions that accept an 'int' as an argument, you could ask for all functions that accept both an 'int' and a 'string' as an argument. Given 3 and "test", the 'repeat' function could be suggested, resulting in "testtesttest".
To make things even better, one could provide (explicitly or not) the return type of the function they're looking for. For example, if you're assigning to a variable of type 'int', and all you have is a 'string', then you probably want to see a list of all functions that take a 'string' as an argument, and return an 'int'. In that case, you would see functions like "parseInt" or "getLength". It's kind of like playing domino, where you already know the type of the input and output, and only need to connect them together. Keep in mind that you can't always transform one type to the other in a single function call, which means the system would also need to recommend combinations of functions, such as "parseDateTime + getDayOfWeek" when you need to transform a 'string' to an 'int'. Perhaps the name of the arguments could even be used as some kind of sorting heuristics (a 'string' variable named "date" surely should be parsed to some kind of DateTime at some point).
The problem is on-boarding - once the user learns to ask for computer a question then the text (or voice) interface has the potential to be on a completely different level than a graphical interface.
Just imagine - instead of searching through a dozen menus for an option you just ask.
Hell, that's how most people work with Microsoft Office now - fumble around trying to find out where they've hidden the option. Fail. Open Google and type "how to change signatures in Outlook 20XX".
Slack solve that brilliantly - their on-boarding is well designed - the way it gradually introduces features and reinforces concepts is excellent. It reminds me of modern videogames in design.
Non-geeks do not use additional search syntax compared to the number using the nice obvious and clickable "Images" or "videos" tab.
I disagree, and I think we can see the counter-example very clearly with altavista.
You could go to altavista and type in "dumb" search queries, just like google.
But simultaneously, with no change at all in the UI and no constraints imposed on the "dumb" users, you could also type in very sophisticated boolean searches like:
linux grep ("regular expression" and "regex")
and get very precise and sophisticated search results.
I miss this every single day
That's what I was trying to get at :)
For the time I'd also argue that their "on-boarding" was excellent: a textbox and two buttons, you can't get simpler :)
The 2015 equivalent would be adding animated instructions in a pencil typeface on the search box and buttons. The demographics and expectations are different now.
A lesser example: half the time I want to use a menu-item in OSX now, I find it by going to the Help menu and typing something in the fuzzy-match box. I'm not sure why this hasn't been made the primary OSX menu interface.
Lycos
Not really.
These type of comments are almost always pure speculation, based on one's own experience.
Here's one thing that is true: Everyone who uses the command line was once a "pleb".
Txt'ing is what its name implies. Typing short lines of text. (And anticipating a quick response.) Seems reasonable to make a comparison to using the command line.
IRC, or today's "chat", is also arguably similar. Typing short lines of text, and expecting a quick response.
I have wondered about this for years as SMS and later Twitter, and now "enterprise chat", i.e., typing short lines of text, became popular.
But winning a popularity contest for how people interact with a computer is not something that really interests me.
My prediction based on last 30 years of computing history is that command line interface is never going to disappear (that is one reason I stick with it). It is there for whomever may discover and choose to use it.
"They don't even know what they don't know."
Exactly.
And yet countless GUI lovers/CLI haters continually ask us to believe that some hypothetical user would _choose_ not use a command line interface when they do not even know that such a thing exists; they were never given a real choice.
Who cares what other users want to use? It is their choice, not yours.
Give them a choice a see what happens.
Experiment.
Good CLI programs have a relatively straightforward path from 'help' to where you need to go. Contrast this with GUI's, which is what people are familiar with:
- The help is basically the instructions manual for your new gadget that you won't read, too detailed, not helpful and you'd rather just play with the thing and learn how it works.
- That's also how people solve problems, by playing around with the available options in the interface or if you are a 'superuser' by googling.
So basically people have been trained not to ask the program for help, they'd rather go on the internet or ask their tech friend for help. Which means they are predisposed to not 'get' CLI programs.
There's also the fact that man pages are way to threatening (and ancient). They should be structured like a wiki (with links between each other and to definitions as well as a conversation layer for improvement etc.).
Telegram bots are CLI programs that follow the unix philosophy (in a sense) and are a step in the right direction when it comes to starting an organic conversation with the user. However they are also very small programs and there is still a lot of improvements to be made.
So no terminal commands don't need to be taught in school and GUI's aren't the ultimate solution. If we were to pour the same amount of effort into improving CLI interfaces as we have with GUI's computers would become much easier to use. However that doesn't mean that CLI's are the ultimate solution either.
Hopefully people will one day realize that personifying tools is actively harmful and that everything is context dependent.
Edit for formatting..
If I had FU money I'd set up a project to improve man pages, coordinating with the other documentation projects.
[1] on Linux. It's a bit different for the BSDs.
GUI are to harvard for me, data and actions are two distinct worlds, too distinct worlds.
On the disagreement part, one thing is particular stands out:
> Interacting with the stream
Only developers care about that.
>Want to know why the command line is hard for plebs?
It wasn't hard for the decades before GUIs. Why is it hard now? Are you conflating not knowing with being hard?
>It's because they don't know what the options are. They don't even know what they don't know.
The same criticism applies for voice interfaces. If the users can expect the command line interface to be similarly intuitive, then it becomes easy.
>This isn't going to change anytime soon. At least not until terminal commands are taught in school alongside the alphabet and multiplication tables.
Why do they need to be taught commands? Maybe the command processors need to be taught different ways commands can be expressed and composed.
[0] http://www.cisco.com/c/en/us/td/docs/security/fwsm/fwsm31/co...
[1] http://zsh.sourceforge.net/Doc/Release/Completion-System.htm...
Please. It's not difficult to do at all. No one needs a GUI, it just makes it easier for "mom n pop" to do their thing.
Not that I disagree on how discoverable a GUI is. However, many of us got that exact experience on 8 bit computers and it proved high value.
There isn't a lot of difference for young people today. If they do learn what a command line is, options, syntax, pipes, arguments, they learn a whole lot. Done in the context of common apps they would use is a very good thing too.
Go ahead, do something productive without using text.
Want to know why the command line is hard for plebs? It's because they don't know what the options are. They don't even know what they don't know.
The whole point of a GUI is to convey the possibilities. Show users a menu and they get to pick something. This isn't going to change anytime soon. At least not until terminal commands are taught in school alongside the alphabet and multiplication tables.