>There is, after all, no fundamental reason a GUI could not be designed with the goal of reification of interaction in mind; it’s just that it is rarely done in practice.
If we have to search for an underlying reason, it's that most GUI interactions by most end users don't need reification and therefore, that code is not put in.
If the GUI has obvious needs for reification, the programmers account for it. Two examples that come to mind are computer chess games, and software audio workstations.
Many computer users who are comfortable with UNIX command line will nevertheless "move chess pieces" by clicking and dragging the piece from one square to another. However, virtually all chess programs still record the algebraic chessboard notation of each move and the players can see the tally of moves scrolling on the side of the board.
The other example has music producers mixing a song. They will adjust the sliders/faders of volume panning and the software will record their moves. It's known in the trade as "mix automation". When the song is played back, the software makes the sliders mimic the same moves. The automation in "reified" into a time graph[1] such that one can move the nodes around to fine tune the movements more precisely than the fingers did in real time.
As for other GUI applications like typical business data entry screens, etc... most GUI toolkits like C# Winforms, C++ Qt, HTML buttons, etc do not include a macro recorder in the default event loop. Therefore, to "reify" the GUI in the same fashion as chess programs or the audio software requires grafting data structures and programming extra code to "record" the button presses into a timeline. Programmers won't do this unless there's a customer need for it. (E.g. Photoshop lets you reify the GUI as "actions" for later playback")
* The interface is typically NOT optimized for keyboard.
Typing E4D5 is not optimized. You need to look at a square in the middle, then look which row it is, and which column it is. I've implemented a better one for a similar game (Jungle). You press a character key to highlight one of your pieces, and the game essentially highlights legal moves by displaying alphanumeric chars on tiles. Instead of 4 keypresses, you have 2. In Chess it could be like this: 1-8 selects a pawn, b/B one of bishops, r/R - rooks, k/K - knights, q - queen, i - king. Then another character depending on what shows up where you want to move.
* People who play realtime chess (one example is Kung Fu Chess)do use keyboard
certainly those playing in tournaments.
E4-D5 notation is optimized for recording games, not for playing.
Paint.net is another example of an application that reifies its actions with a nice 'history' window that shows the semantic actions that the user has performed and allows you to jump back to earlier points in your history of editing the file. GIMP does something similar, it seems particularly common in image editing programs.
I was thinking about this just a few days ago. This seems like a much better way of teaching people shortcuts than a 20-page cheat-sheet or even "hints" in various menus. No UI clutter, no effort. The program just tells you how to do the same thing in another way. The more you do the "thing", the more likely you are to notice those tips and try out the shortcuts.
I don't think Paint.NET or GIMP do quite what you've described though. They show a history of action, but they don't show commands.
Now I don't have lots of experience with Blender, but I do remember that Blender when hovering a button shows the Title of the interaction, but also a description, shortcut AND the equivalent python code you can run in the terminal to achieve that action. That's pretty awesome.
You also see this in chip design EDA tools, at least the good ones. Not only will they record the equivalent CLI command that affects the "data", but some will also record the commands that solely affect the GUI! (e.g. resize window)
That reminds me of more extreme work like Bret Victor’s drawing dynamic visualization demo, where drawing commands are reified and can be manipulated/abstracted in place. I saw Dan Ingals do this with some of his work, but can’t find a link ATM.
It's a common technique for document-centric editors in general, because it's usually also the best way to implement multi-step undo. Once you have the steps recorded anyway for that purpose, surfacing them in UI is straightforward.
I'm curios what you mean by this. I've been working on some software called textgraph [1] (not yet ready for use, and now internally renamed gradesta ) for a couple of years now, so anything with "graph" in it makes my ears perk up.
the paint.net stacked history is similar to what was used in 3D studio max in the 90s. It was "cool" but too linear (it's a stack after all).
Other software like Houdini or Maya (or NR Shake) used DAG (acyclic graph) of operations to create an output scene/image. There the history isnt linear it's a bit of a multiverse, you can disconnect part of the graph, try new things, reconnect. Everything is there.
Though as you mention, many developers nowadays don't see the need for history, and so are putting application/webpage state somewhere other than the router. This IMO is short-sighted, as it undermines the transparency of a user's actions on the web. And plays into the walled-garden effect many of these same developers will lament in the loss of the "open web".
I don't agree that we've lost this ability by moving state to the client or JS (since it seems you're really bitching about single page JS apps).
There are several ways to capture that state, and the nice thing is that the browser allows sites to either opt in or out depending on their requirements.
See: Insights, FullStory, or any other event hooking library.
We can also play back those actions using the very nice WebDriver apis available in modern browsers.
There is zero reason to assume that we've lost reification simply because we've moved away from an approach that requires at least one RTT in latency before updating what the user sees.
I think if you use JS your website has broken history by default and you need to go an extra mile (or use a nice framework) to remedy this. And there are things like infinite scrolling pages. And then you find yourself arguing with the developer why it should be fixed ("Yeah ? But nobody uses history anyway.")
If you use C your program has broken history by default and you need to go an extra mile (or use a nice framework) to remedy this. I guess the difference is that in C world, we've more or less standardised on a few nice frameworks (Qt, GTK, etc).
Further, there are a HOST of tools that make this process very easy, complete with replay solutions, detailed logging, real time monitoring and all sorts of other fantastic, modern tools.
Just because you choose not to use them doesn't mean they don't exist. Sorry your understanding of web dev is out of date...
> most GUI toolkits like C# Winforms, C++ Qt, HTML buttons, etc do not include a macro recorder in the default event loop. Therefore, to "reify" the GUI in the same fashion as chess programs or the audio software requires grafting data structures and programming extra code to "record" the button presses into a timeline. Programmers won't do this unless there's a customer need for it. (E.g. Photoshop lets you reify the GUI as "actions" for later playback")
In the MacOS System 7 days when Apple was still pushing AppleEvents/AppleScript heavily, a good portion of Mac software would let you record your actions in them through the AppleScript Script Editor (they would emit the AppleEvent equivalents of your GUI actions), generating an AppleScript which you could then edit. It was a fantastic system. It's still there in macOS X, but it's rarely supported/used now.
Both of the GUI toolkits I've worked with (GTK and Qt) have a concept of "Actions" which can be (and frequently are) mapped to a menu item and a keyboard shortcut and sometimes a CLI flag; isn't this an example of reification, or am I misunderstanding the concept?
Sure, but is that implied by "reify"? My understanding is that they are reified and thus it is possible to make a timeline from them. CLI commands are only recorded into a timeline because of shell history, after all--if you call a CLI from a different mechanism, does it become not-reified?
Hell, often it is useful to launch a X11 program via a terminal as they will dump useful messages that way.
And said output can also be captured in logs elsewhere.
One example of such would be SMPlayer. This is a Qt based media player that wrap MPlayer (and more recently the MPlayer fork MPV). But you can still access the MPlayer CLI output by either launching SMPlayer from a terminal, or going opening the log window from one of its menus.
The undo stack of any document oriented application is that timeline? Typically if you hover the undo button it says "Undo add frob" and if you undo that, you can see the next item. It's also common to be able to drop it down and see the whole undo stack and undo to an arbitrary point in it.
Since this has been par for the course for for as long as I remember, I take it that's not what's discussed here...
Many apps (or app windows) have actions, but not undo stacks. Undo stacks are typically only used in app windows that display a document of some sort, and then the stack is limited to actions on the document. Have fun trying to revert the last 10 app configuration changes.
Right - the undo stack is always for a "document" of some kind, and more importantly a single user view of a document. Multiple documents can be used (with a single or separate undo stacks) and a settings object can in theory also be viewed as a document although this is rarely the case.
A manager once asked for full undo in a GUI for a shared db. That's not possible...
My point was that if actions are dependent and undoable then they form a stack. If everything can be undone then all that you are affecting (including view state, config, ...) has simply become part of the document.
In the app I'm developing I'm distinguishing "actions" as being what a shortcut/button/menu item represents and "commands" as being document modifications.
Actions aren't necessarily undoable ("quit" is an example) but most actions end up as being commands, and those commands form the undo stack. Actions handle availability (enable/disable) etc. I think this is a fairly standard pattern for document based applications.
Reification is always there for the (rare?) cases you need it. With GUI, there's no such option, and it's hard to notice something that has always been missing.
They reify UIs, but discoverability of functionality can be a real problem. Git, of course, is the classic example, because its "UI" is a hacked-together mess compiled over years and years and features were added piecemeal. But even for green-field CLI tools, it's a problem.
The real value of CLI tools is extensibility and scriptability. You don't have to rely on the application developer inserting UI hooks everywhere; you just write a shell script, and in the absolute worst-case scenario use Expect to automate interactive processes. And adding a new subcommand is relatively trivial. The code is typically easy to trace the user input down to the internal machinery. The UI is a very simple function dispatch and argument-passing mechanism. There are no widgets to worry about, no switches or boxes to position.
Therefore CLI tools will always be beloved by power users and feared by everyone else. If you know exactly what you're doing, they can really speed up your workflow and provide and interface for precise, expressive control and automation. Otherwise, all but the best-designed CLI tools are intimidating and difficult to master. Who can remember all those switches? Having a bunch of labeled buttons laid out in a UI leads to a much lower cognitive load.
IMO the real value is in CLI applications that can be embedded in a GUI, but are embedded transparently, in that the GUI can be scripted by simply scripting the underlying CLI. Git (Git GUI, GitHub, Tortoise, Tower, etc), Apt (Aptitude, others), TeX (Tex Live Manager, kinda), and others have good interfaces along these lines, but we're definitely in need of a good CLI interface for Rsync and Tar. Many CLI wrapper GUIs tend to be opaque and don't expose enough underlying functionality.
One standard for history-keeping is the following: If we start with a clean system, and replay all the commands from the history, will we end up with the same system?
This is how Lighttable, Photoshop, and other Adobe CS products work. Also the Vim "undo tree" to some extent. It's an excellent feature.
From personal experience, many users fear all UIs. This because they fear that their actions will be irreversible more than anything else.
And frankly i suspect that CLI gets a bad rep because MacOS never had a CLI to begin with (OSX got one via its unix internals, but i am unsure Apple knew to value it), and DOS was minimalist to put it mildly.
Sadly this has lead to unix UI devs to disparage the CLI when they should embrace it. That a X11 GUI tool is a wrapper around CLI tools is not a hindrance but a boon.
It means that if the CLI tool behaves correctly, the GUI tool will as well. And if the GUI tool behaves incorrectly, the user can try the same in the CLI to see where the problem originates.
It is really sad to see the push towards using dbus rather than CLI to communicate between GUI and daemon, as so much potential information is obscured in the protocol.
That is very different from how I remember history. At least in Norway (and Nordic countries in general I presume), Apple never had much presence. Whatever they thought of the CLI, was rather irrelevant. Amiga and PC which was both popular in the 80s both had a command line.
I'd rather say that it was Windows which made the CLI look bad. They made people think that CLI means old fashion technology. Amiga like OS X had a window system and CLI from the beginning and so users did not view CLIs as old fashion technology but rather as one of several alternatives.
My experience from the time was that it was mainly PC Windows users who talked down CLIs because they viewed DOS as a antiquated. In some ways it makes sense as the DOS CLI has been horrible for decades and MS never put any effort into making it nice.
I'd say OS X could be thanked for resurrecting the CLI. I still encounter Windows developers who almost don't know about the CLI and who never uses it. I don't think you find and OS X developers in the same position.
Mac in Norway is an odd duck. It never caught on as a wide consumer computer, but has maintained a presence as the primary computing platform in media production.
cmd.exe is still horrible and PowerShell looks like more a programming language rather than a true shell. ConEmu makes cmd/PS more usable, but it is still very far even from bash CLI, not to speak abput zsh.
> And frankly i suspect that CLI gets a bad rep because MacOS never had a CLI to begin with (OSX got one via its unix internals, but i am unsure Apple knew to value it), and DOS was minimalist to put it mildly.
Macintosh didn't have a (built-in) command line for a long time, but it has supported scripting for a long time, starting with System 7 in 1993.
And, Macs had a debug button that when placed on the Mac and pressed dropped you into a low level debugger CLI.
And prior to AppleScript, there were a few other CLIs on early Macs: Terminal programs like telnet, the CLI in MPW, and CLI / scripting in Applications like HyperCard and others IIRC.
> IMO the real value is in CLI applications that can be embedded in a GUI, but are embedded transparently, in that the GUI can be scripted by simply scripting the underlying CLI.
This is where your CLI application becomes a de-facto API and the wrapper has to anticipate and handle any output from the command. It's an astonishingly brittle system (have fun using any GUI around CVS) to the point that in many cases the GUI doesn't actually wrap a CLI application, but instead uses a library (e.g. most Git GUIs probably use libgit2 instead of calling the CLI). Libraries tend to have better designed interfaces for other programs, you don't have any problems with shell quoting and you don't try to shoehorn an interface for users into one for programs.
Some tiling window managers work this way without any issues.
Bspwm[0], for instance, uses a client CLI program (bspc) to send commands to the daemon and alter its configuration at runtime.
In fact, it doesn't have a configuration file format at all, since it can be configured via a simple shell script that runs a sequence of bspc commands.
It also doesn't have any key binding functionality and offloads this to a separate program, sxhkd[1], whose only purpose is to interpret key presses and execute shell commands. Since this is bspwm's interface, the two work seamlessly together, even though they're not dependent on each other at all.
This is just brilliant design, and speaks volumes for the "do one thing and do it well" school of thought.
For the record, I've been using both programs without a single issue for the past 3 years at least, and it's been one of the most stable and least problematic systems I've ever used, and use to this day.
So just wanted to offer an opposing personal experience (anecdotal, to be sure) regarding your brittleness concerns with this interface.
I don't agree about discoverability. The great thing about command line tools are man pages. You have a reasonably consistent form of documentation across different tools. And the options are invoked in the same way. In comparison with UI tools you have to navigate menus and options which is hard for unfamiliar software. And the documentation always has to explain UI steps rather than just the options. For command line I can easily search and scan man pages to get a complete view of what the software does.
Instead of one big GUI app in CLI you often supposed to use combination of smaller tools. When you know which tools you need you can read man pages for them. But it is not easy to discover which tool you need. Especially in Linux where you need install it first.
Other problem: man pages are too long to read because modern CLI tools are cluttered with lots of rarely used options. I wish developers followed Unix way [1], but trend goes in the opposite direction.
I'd consider the front panel of physical buttons, switches, knobs and dials of early, pre-teletype computers to be much more like a GUI than a CLI. We circled back around to buttons and sliders, with state display laid out in 2D in ways our brains enjoy.
But if we play this game you I could counter with "consider slaves, they pre-date control panels but took textual (or at least verbal) commands". It's a silly game isn't it?
But we can gain some knowledge from the game nonethless. Control panels do have some great benefits, because the human vision system is so powerful, and because there is the possibility of direct manipulation.
But the CLI has the great advantage that you are just telling the machine what to do, instead of having to point and grunt. But it's not good for ordinary users because the language is baroque while also requiring you to talk very precisely.
We missed a lot by being slow to develop "fuzzy CLIs" where people can talk more lazily. The "press the windows key to search" feature from Win7 onwards is a good start in this direction.
I consistently surprises me how many people can't grasp the advantages of both approaches CLI and GUI.
For me the key thing about CLI's is the same as the benefit of plain text in the traditional unix style of thinking.
When your interface to any functionality is plain text you have the advantage that you can use any number of generic tools to manipulate that interface.
One example is how visual programming languages are mostly failures. It doesn't take long before the inherent problems of composing a program in a GUI is made clear. Text is easily malleable.
You see this on many levels. You might be in an IDE and need to change a value of multiple settings or duplicate some setting several times, except there is no tool in your IDE to actually do a substitution of values in arbitrary settings or do duplication.
However when settings are represented as just plain text, this becomes a trivial matter to solve.
One of the reasons I love macOS so much is that from the very beginning of OSX Apple made the interaction between GUI and CLI very smooth. They both have strengths and I am no fundamentalist, and so they should work well together. You see that in how Apple early supported things such as dragging and dropping objects from the GUI into the terminal.app or the "open" command which allowed you to invoke the appropriate GUI tool for a given file type from the CLI.
The Plan9 guys probably went furthest in this. They seemed to have woven GUI and CLI thinking tightly together.
If you use Symbolics Genera (or the Common Lisp Interface Manager, see for example McCLIM), the GUI interactions will seen as 'gestures' and not as clicks. For example there could be a Select gesture. These gestures then invoke commands. The commands created by mouse gestures will be recorded in the interactor history like a command which has been typed to the interactor. Pointer gestures are : select, describe, delete, menu, edit,
Thus one gets a history of commands, which also can be reused, even from mouse gestures. Selecting a command from a menu or direct manipulation usually will lead to a recorded commnand in the interactor. The interactor runs a command loop.
CLIs are (or can/should be) composable. This is what really makes functional programming languages so powerful -- they give you a few connective frameworks, and a box of components that can be glued into them, and one can compose great things from simple things.
Or, in other words, "|" in the shell is "." in Haskell (with operands reversed).
> Or, in other words, "|" in the shell is "." in Haskell (with operands reversed).
Well for real power you also throw partial application and arbitrary sub-lambdas / case-switches / let-binders into this mix and now that basic 'pluggable' composability truly shines =)
It's really powerful in one sense (the composing part) and so limiting because you immediately force applications to talk in lowest common denominator speak.
It's exactly like the dot in haskell but you have no types. Haskell without types is pretty terrible.
The Morphic framework in Squeak Smalltalk was an excellent example of this idea. Every object essentially had a little REPL+IDE attached to it. The more standard Smalltalks weren't far off from this either. In just one afternoon, one of my coworkers wrote a utility allowing him to command-click anything in the GUI of our app and open a browser and inspector on it. The reason why he did that, is because he sorely missed an even more powerful utility of this type from his Symbolics Lisp days.
Regarding the benefits of CLIs, "reification" is only one benefit of many:
Economy:
Graphical protocols like X or web standards are much heavier over the wire than text, and are often not suitable for many use cases. There is also economy of movement, moving the hand back and forth from keyboard to mouse or up to the screen to tap.
Consistency:
Text is a relatively simple data format supported everywhere. Cutting and pasting data with images and formatting, for example, is often a mess or doesn't work.
Precision:
Mouse (and touch) input is imprecise and frustrating analog experience. Clicking on a specific point requires moving to it and not missing it. Grabbing an edge of a window is the least elegant gesture ever created. Text entry is precise and digital.
I absolutely agree about the benefits of reification.
In addition to creative authoring tools such as Photoshop which others have mentioned, I want to praise Microsoft's SSMS (SQL Server Management Studio). Some years ago, I had spent some time DBA'ing MS SQL Server and really enjoyed that tool. It's an extremely discoverable GUI for managing this very complex DBMS, and before every operation you perform through one of its wizards it would show you the T-SQL command it generated to perform that action, so you could review and/or script it.
"Reification" has a fairly clear meaning in CS: basically, it refers to a situation when some feature in a language is made available as a value that can be "passed around" in the program and used somehow. Closures are a reification of functions and lexical environment; continuations a reification of control flow, etc. Classes can be reified as objects, so that we can receive a class as an argument and ask that class to spin off an object of the type that it represents. The va_list type in C reifies function arguments (at least the trailing ones, of a variadic call) so then they can be passed to another function or functions.
We can take as our model of a simple UI the "dialog box", in which a user can prepare some inputs, and then submit. The "dialog box" corresponds to a function with arguments, and the sumbmission is a function call. So of course, in an underlying programming language, the equivalent can be reified as a first class function.
Even a relatively unsophisticated textual CLI can "reify" that at least by turning the concept of a "command" into a string value: there can be a variable that can hold a command, which can be passed around, dynamically calculated and altered, and executed.
The UI usually has no straightforward equivalent of "generate 100 instances of this dialog box invocation, feeding successive values from this list into the ID field ...".
That sort of "reification" can occur with tools that automate the generation of events into the windowing system.
Graphical frameworks in which you can make "actor" objects and hook them up are kind of a reification of the GUI.
I use the command line a lot for web dev but wouldn't say I was a real power user.
Pain points for me are discoverability and ease of making dangerous mistakes. I can't remember the command for every useful utility and it's very easy to accidentally break lots of things. Great power comes with great responsibility and all that.
What tools do you use for auto-complete-ish features on the command line? or anything to generally make using it easier.
Prezto for zsh has pretty good command line completion and a lot of plugins which are either on by default or available for you to flip the switch on. It's taught me some nifty bits of git, gpg and some others. https://github.com/sorin-ionescu/prezto
I personally prefer working on a command line because it's _more_ discoverable to me than most gui's. This did take some getting used to though. The approach is different.
The worry over making dangerous mistakes is understandable. That said I have made very few big ones after a bit of learning, and it has also helped me _avoid_ making dangerous mistakes by facilitating the automation of otherwise delicate or involved tasks which would be unpleasant to click and type through.
I think you're confusing CLI (an application interface) with a command line. I would argue that CLI applications are inherently more discoverable than GUI applications, if only because `cli --help` or `man cli` give you a pretty complete overview of the functionality; the GUI equivalent is digging through menus and modals--this is getting better with Help->Search, but it's not as nice as `cli --help | grep <feature>`.
I think the real usability issue of CLI is that their potential is handicapped if you don't know how to compose these programs, etc. In other words, if you don't know your way around a Unix command line, you're not going to be able to make use of the tool that assume that knowledge.
I think this is different than what you're saying, but maybe I'm just repackaging your points?
Notebooks a la Jupyter do have all the qualities described in the article in graphical form. In fact any programmable system that allows combining multimedia objects could be shaped as a graphical CLI.
That kind of system would have been very hard to make with object oriented programming. But thanks to the recent advances in programming languages supporting asynchronism and composability, we'll see more of them.
Interesting that as an example of the benefits of 'reification' the author gives the ability to copy/paste commands to execute them again.
Of course, this interaction with the command interface - that of selecting the previous command, copying it, then pasting it - is not 'reified'. It is executed through the - we may have to admit it - graphical interface through which you are interacting with the command line interface. It's not a purely textual interface, after all, since it includes graphical elements like a cursor.
As an experiment, consider that a voice assistant like Alexa or Siri is also effectively a command line interpreter, but that in those cases 'copy paste' is not available so easily. 'Siri, repeat back the last command I gave'?
So maybe the interface that is being praised here isn't the command line but rather the graphical interface in which a command-reifying interface is hosted...
That's a bit of a stretch. I get by just fine in the console without making any real use of its gui-ness; !! is a lot more efficient than reaching for the rodent. Actually, I'm in the process of switching to a framebuffer console -- I mostly just need to get emacs to make use of my truecolor implementation and I'll be X free.
Sure, but your !! command isn't reified. Any edits you make to a command plucked from your command history aren't reified.
I didn't say anything about using a mouse to interact with the CLI - copying and pasting don't require a mouse, but they do require a UI through which you can see what you're selecting and copying, even if it's just cursor key driven. And it's the original article which suggests copy/pasting commands from web pages or docs into your CLI, as well.
You can copy and paste in a CLI as well. I often chain pbcopy/pbpaste (OS X, I used similar but differently-named commands on Linux) into scripts rather than temp files or input files. And ultimately, that's what a pasteboard is: a temp file, as used by CLIs for ~70 years.
One supremely nice thing about *nix-style systems is that most programs will barf a number of complaints along the way to failure, while Mac/Windows counterparts typically fail silently or log errors to a mysterious per-app location.
I've always wondered why every application doesn't just have a shell console hanging off the bottom of the window, the way browsers do.
We've already had a half-assed version for decades, part of nearly every GUI ever (though they're falling out of fashion these days): "status bars." And most OSes also already have a "scripting" mechanism that requires applications to expose a specific "scriptable API" (WSScript requiring ActiveX components on Windows, Automator requiring Apple Events on macOS.)
So just combine the two! The OS could have a "status-bar control" that you'd stick onto your main window of your app, which would start as a regular status bar, but have a little disclosure arrow—that would turn it into a full historical log of every previous "status", plus a REPL for entering script (probably with a dropdown to select which of the OS's available "scriptable languages" you're writing in.)
If you don't want to muck up your GUI, you could simply detect whether your GUI app has been launched from an interactive terminal (i.e. whether stdin is a PTY) and then provide a regular REPL-like interface on the terminal. A lot of GUI apps already log to stdout in the expectation that developers will be running them from the terminal; why not just add some more interactivity the same way?
---
I should also mention a third, much less obvious route: Plan9's Acme editor, which isn't so much a "GUI editor" in the normal sense as it is a text buffer with a configurable space of API commands hanging off of it.
In Acme, the menu system (and its associated keyboard accelerators) are effectively just another text file that you can tab into and edit. Each thing you write into the menu is just a literal API call. Hitting that menu item will then call that API, passing the selection or the current buffer as necessary. [It's actually even more universal—in Acme, left-click selects and middle-click activates. You can write a command anywhere and then middle-click it. The menu just provides a convenient holding place for middle-click-able text.]
Acme has its own internal commands—sort of like Windows PowerShell—but it also allows you to just write regular shell commands into the menu as well. Activating a `wc -l` menu-command will literally just dump the output of `wc -l` into the status bar. Activating `tr A-Z a-z` will literally just tr(1) your selection/buffer into lowercase. Etc.
And I fudged a bit: the commands that are "internal" to Acme are just shell commands too. Since we're talking about Plan9, every process has its own environment, so Acme has a set of internal binaries that end up in its own /bin. These little "command" programs just use RPC to send commands to the current Acme instance. So the "scripting environment" here is literally the shell itself! (And you can "script" Acme from outside it, too, by mounting its command-binaries from wherever it keeps them, into your process's /bin dir.)
Not a native english speaker here, could someone explain what exactly "reified" means in this context? I tried searching online but it only led to further my confusion!
"reified" comes from the Latin "res" meaning "thing". It means "to make an abstract idea or concept into a real thing". For example, the Turing Machine model of computation is reified in the form of actual computers.
GUIs might be easy to use (e.g: IIS manager), but when you have to manage 50 machines, programability is important and automation becomes more important.
Yeah anytime someone says GUIs are “easier” my question is always “for what?”. Not because a CLI is always (or even usually, depending on how you slice it) superior, but because a GUI makes some things better and some things a lot worse. So many use cases are not “easier”, they’re harder.
And why, after so many years, MS introduced Powershell.
Now you can do a GUI-less Windows server install, as manage it completely over the CLI.
Never mind that with Windows 10 there is no damned way to tell Windows to request a new address from DHCP if the initial attempt failed. The only way to do so is via the CLI and ipconfig.
Powershell is fine. However the Windows philosophy is different.
In Unix, "everything is a file", and what is not a file, is a program that can be configured or a CLI with arguments that can be passed in programatically.
I think what a lot of GUI's fail to do is to just get out of the way when it's failing to accomplish whatever task is at hand. You don't have the problem with CLI's most of the time because you probably have to implicitly compose commands to achieve the same thing the GUI might do in a single click.
A button might kick off a set of tasks and aggregate the output into a final success message. If it doesn't work there's almost no way to dig into what's going on or even attempt to get the program to an acceptable state with whatever data you're working with.
A CLI might have an analogous command that also kicks off a set of tasks but if it breaks/doesn't work and assuming the CLI is following a unixy model, you can run through specific commands diagnosing the issue or at the very least get to an acceptable state in your workflow that leaves you with a few options to work with.
Any GUI, in my opinion, should just be a visual abstraction from a set of executable tasks that can be run individually. Take something like Github's Desktop client. In yester-years, when it first came out, it was pretty bad at handling git rebasing operations. But because of the way git was built and used most of the time, the Desktop client actually just called into the gitlib API or even just straight up wrapped git commands. If something broke, just like rebasing, I could actually take to the command line, inspect the state of the repository, and continue with rebasing via the vanilla git commands. And even then, when a git command doesn't act right, it might actually just be a wrapper around other more internal commands that you can execute yourself (i.e., git pull is actually analogous to git fetch; git merge origin/*). Compare this to a TFS error I've been getting for a few months on a legacy repository, with little to no information across application and system logs, and almost no information via google: "Provided parameter is not valid." Neat.
I wish the described "composable application" if you will was just a standard across every application. Even in web applications I build I make sure there are "steps" in data processing instead of just monolithic operations. I take care to make sure steps can be kicked off individually with sane output. It seems like we lost this philosophy along the way across every level of application development and the linux ecosystem hasn't been immune from this in my experience. Windows has never really stepped foot in those waters until recently with PS. But most of the time, in my experience, we get GUI's with no recourse. If it breaks you just might be out of luck until a patch comes in or you can interact with the data yourself.
Maybe one day if a program (even a web app!) doesn't provide a set of clean commands to run we'd look at it like we do a badly designed GUI, with disdain and disgust.
The author makes a valid point. Consider command line history, and command line editing via vi or emacs bindings. I use sh like a REPL all day, every day. I make constant use of searching prior tasks with Ctrl-[ + / or fc -l. I also have hundreds of short, saved scripts.
I do not use a mouse or X11, no vim. I do not use a "clipboard", other than tmux buffers. Everything happens through editors/pagers like sed, vi and less. There is constant iteration. What is the GUI equivalent? Keyboard macros?
The ultimate aim is to make tasks non-interactive. To script away the interactive work. Automation. This is in direct opposition to the philosophy of the GUI: that work must be interactive, and to make interaction more pleasant.
But there are so many differences and similarities between CLI and GUI. What really separates them and makes me choose one over the other? If I can pick just one point of differentiation: Most times, CLI is more reliable. What does reliable mean here? It means robust. Less likely to fail.
Assume that for comparison we can have both GUI and CLI versions of the same applications. And that the GUI is more than just a "skin" over the CLI.
Show me a GUI application that is more reliable than the CLI version. I will take notice.
But to get me to switch away from CLI usage, one must show me many GUI applications, all more reliable than their CLI versions.
An entire system of fast, robust GUI applications, all more reliable than CLI alternatives.
This might be possible. But it is not available as of today AFAIK. And I have to go with what works. Today.
Well now I'm really curious about your actual software use-cases here. Because regardless of whatever "end user not dev" use-case I can think of, out of the many multiple dozens that instantly spring to mind, I cannot name a single one that has not had for 1-2 decades multiple well-known, widely-used-daily, best-in-class apps or suites on the market that are fully GUI-no-CLI and are at the very least evidently "reliable enough". Whatever GUI app I have used in the past 10 years, we can talk GIMP/Paint/VS/Sublime/VLC/Photoshop/Lighttable/LuminanceHDR/Blender/Unity/Unreal/VScode/Thunderbird/Firefox/Chromium/archival-tools/file-explorers/countless-others --- not only have they been utterly reliable and predictably delivered as was demandedd, their CLI alternatives hovered between non-existent and underfeatured.
So "end user not a dev" to me sounds like you must be a sys-admin or maybe, "author of man pages" ;)
About half of those guy apps you're presenting are irreplaceable. The other half are not. GIMP, Paint, Photoshop, Lighttable, VLC, LuminanceHDR, Blender, firefox, chromium (image/video viewers/editors, web browsers) are all about looking at, creating, and modifying things that are graphical in nature. Thunderbird, a mail reader, is about looking at things that are textual in nature. Same with file explorers, archival tools, and text editors. These things work fine with a cli interface. Unreal/unity are a bit of a special case -- there's nothing that does exactly what they do from cli, because that's impossible, but it's more than possible to create large playable graphical video games directly with a text editor and a cli -- even if it's not possible to play them that way.
I don't have a lot of experience, but I suspect that many visual applications could be greatly improved by a well defined command language.
The various dialog boxes and widgets in apps like Gimp and Inkscape always seem fussy and annoying to me, especially when I know exactly what I want. If I could talk to the app, I would say "put margins 2cm from the page edge" or "position object X halfway between objects Y and Z", etc.
Blender has a Python console, and it's even somewhat discoverable because you can find out how to script an action you do in the UI, but the Python API is too verbose and ugly to be an actual daily mode of operation, I think.
Sure, there can be a textual component. This works out well and is even necessary in, e.g., game engines. But ultimately you're modifying an image and you need to be able to see the modifications as you make them even if the way you're making them is with the keyboard.
All of the software you mention has had, over the versions, introductions of major bugs, regressions, UI elements changing for the sake of it, features available in a previous version being removed in a subsequent version (sometimes to be reintroduced later)...
Is that your definition of utterly reliable and predictable?
> But to get me to switch away from CLI usage, one must show me many GUI applications, all more reliable than their CLI versions.
There is an enormous number of GUIs whose purpose is to make things quick and discoverable for transient use cases. In those cases the user may only need the application to perform their task one time ever. In those cases the learning curve for a more expressive system is too high a price to pay.
Graphical interfaces are useful to me personally because unlike a CLI, there is substantially less in the way of functionality that I have to remember, especially for programs which I rarely use. It is painful to input -h args and read through pages and pages of options to find a handful of the options that I need, especially when I am using something new.
I've given light thought to the possibility of writing some kind of hybrid which acts as a general purpose terminal, but can somehow provide more information in a graphical manner-even something like directory traversal would be drastically simpler, IMO. Of course, this is not a trivial problem.
Are there any existing shells which hybridize GUI and CLI?
Some of this depends on what you are used to. I prefer the command line myself but all my colleagues have these graphical interface things going on. So when I am working collaboratively on someone else's machine I have to endure things like graphical file browsers. This works great if you are working with images and need to see the thumbnails to visually identify something. But for me, seeing a GUI view of files, I can't make sense of it. It takes me time to scan and find what I was looking for. I would prefer to see results from the 'find' or 'ls' command. I can see what I am looking for that way but my colleagues don't understand what they are looking at.
This gets worse with applications. For instance there is a web server control panel called 'Cpanel' that people buy into because they don't want to do the command line. This one really is a 'sea of icons' and I have no idea how you are supposed to work like that. But to people who don't appreciate that on a server you probably want to just run a few things (all available in the history file), the 'sea of icons' provides a lot of help.
Those of us that use the command line are 'having a conversation' with our computers and 'teaching' these machines to do stuff. Meanwhile, the GUI folks are true 'users', there is no 'conversation', it is a fundamentally different relationship.
Some CLI utilities have code completion but it's not great. I don't see any reason why you couldn't have good code completion with pick lists and inline documentation like IDEs. Its kind of frustrating that we are stuck with bash when this problem (API discoverablity) has been solved a long time ago.
I find with CLI there is much less to remember over time due to command history. If I ever ran the command in the past, I can see exactly what I ran. I don't have to remember as the computer does it for me. The only possible tweak this involves is upping your history, as many shells default to a short history.
CLI is nothing more than a form of GUI. Hence GUI is fundamentally superior and the only ones willing to live in the Stone Age of CLI are some coders. What is more ironic is people who think that any CLI can come remotely close to the power , flexibility and extensibility of GUI. There is literally nothing that the GUI is not great at,it’s just that most coders have no idea how to design a GUI and that is reflected in the terrible state of GUI APIs and coding in general. I have been coding 30 years now , started from CLI and as soon I could converted to GUIs and never looked back.
If we have to search for an underlying reason, it's that most GUI interactions by most end users don't need reification and therefore, that code is not put in.
If the GUI has obvious needs for reification, the programmers account for it. Two examples that come to mind are computer chess games, and software audio workstations.
Many computer users who are comfortable with UNIX command line will nevertheless "move chess pieces" by clicking and dragging the piece from one square to another. However, virtually all chess programs still record the algebraic chessboard notation of each move and the players can see the tally of moves scrolling on the side of the board.
The other example has music producers mixing a song. They will adjust the sliders/faders of volume panning and the software will record their moves. It's known in the trade as "mix automation". When the song is played back, the software makes the sliders mimic the same moves. The automation in "reified" into a time graph[1] such that one can move the nodes around to fine tune the movements more precisely than the fingers did in real time.
As for other GUI applications like typical business data entry screens, etc... most GUI toolkits like C# Winforms, C++ Qt, HTML buttons, etc do not include a macro recorder in the default event loop. Therefore, to "reify" the GUI in the same fashion as chess programs or the audio software requires grafting data structures and programming extra code to "record" the button presses into a timeline. Programmers won't do this unless there's a customer need for it. (E.g. Photoshop lets you reify the GUI as "actions" for later playback")
[1] example yellow line graphs the fader or knob changes: http://cdm.link/app/uploads/2014/06/logicmixing-640x399.jpg