10 ms·
Programming Languages are the Least Usable, but Most Powerful User Interfaces
- AdrianRossouw 12y agoYeah. I've come to realize that the hard way. It is also what it comes down to w.r.t. code-over-config. To make a system sufficiently configurable, you end up having to re-invent a turing complete language inside it's configuration files, so it starts looking more like lisp. This is due to the [1] Inner Platform effect. The only interfaces I know of that's expressive enough to drive a turing complete language is either flowcharts, or actual code. This is kind of why I feel that systems like gulp are just superior to grunt, because ultimately the config format can never be expressive enough to solve all the problems, and there's just so much less work to write-what-you-mean, the first time. properly. This also relates my newly adopted philosophy w.r.t. software complexity. [2] Simple vs Easy. [1] - http://en.wikipedia.org/wiki/Inner-platform_effect http://en.wikipedia.org/wiki/Inner-platform_effect [2] - http://daemon.co.za/2014/03/simple-and-easy-vocabulary-to-describe-software-complexity http://daemon.co.za/2014/03/simple-and-easy-vocabulary-to-de...
- coolsunglasses 12y ago>To make a system sufficiently configurable, you end up having to re-invent a turing complete language inside it's configuration files, so it starts looking more like lisp. You need dependency injection too, unless you're going to let people just smash the definitions of existing code. A good demonstration of safe, powerful, and type-checked configurability is Xmonad. http://xmonad.org/ http://xmonad.org/
- ericHosick 12y ago> To make a system sufficiently configurable, you end up having to re-invent a turing complete language inside it's configuration files... Isn't source code basically a configuration file for the compiler/interpreter? > because ultimately the config format can never be expressive enough to solve all the problems And if so, I don't think this statement is quite true. Source code is expressive enough. Configuration files give us flexibility but not expressiveness. Source code, as it exists today, gives us expressiveness but not flexibility[1]. This disparity should be a big red flag that we are doing something really wrong. This disparity, in my opinion, is caused by the abstraction we use to communicate information between systems within source code: parameterized sub-routines. A programming language that doesn't use parameterized sub-routines is basically a configuration file. This gives us both expressiveness and flexibility. [1] Flexibility is within the context of config-vs-source code and ops post. Programming languages are very flexible when you know them.
- kyllo 12y agoWhat would be an alternative to parameterized subroutines, though? Is there another way to avoid re-implementing an algorithm every time you want to use it? And keeping all source in one gigantic file?
- ericHosick 12y agoThink something like messages with behavior[1]. Think objects where behavior is implemented in properties: a single "makeItSo" property for example. Every object has the exact same behavioral interface. The exact same behavioral interface means there is no specialization: every message looks the same. We can compose programs (behavior) by hooking up objects/messages as opposed to coding them. This is because we have 100% encapsulation[2]. We need to know nothing about the internal working of an object since it has no parameterized subroutines. The abstraction for passing information between sub-systems are these messages (every object is a message) as opposed to parameterized subroutines. [1] We could call it message-oriented programming (not to be confused with message-oriented software/frameworks). [2] Even a single parameterized method leaks some of the internal workings of an object and leads to specialization of the objects interface. This also leads to tightly coupled software systems.
- kyllo 12y agoAren't you basically just talking about Smalltalk/Obj-C style message-passing rather than method-calling? But perhaps with more complete encapsulation? That's a step in the right direction perhaps, but I don't really see how it obviates the need for interfaces--you still need to know what messages a particular object can respond to, don't you?
- ericHosick 12y ago> you still need to know what messages a particular object can respond to, don't you? Messages don't need to know what messages they can respond to as all messages have the same behavioral interface (the "makeItSo" property). Where messages expect certain informational properties (information interface) then, ya, the message would need to check if the message passed to it contains the information it requires (such as a UX layout engine that is waiting for UxControl messages). If you have some time, here are some examples: An example using addition: message Add ( left 5 right 6 ) or it could be message Add ( left Subtract ( left 5 right 6 ) right 6 ) or it could be: message Add ( left FromFieldGet ( name "someForm" field "left" ) right FromFieldGet ( name "someForm" field "right" ) ) In all these examples, the Add message does not need to know anything about the messages provided to it in the left and right property (5 and 6 are actually messages themselves). The last Add example uses a message FromFieldGet that is able to locate information from a form (in this case named "someForm" with a field left and a field right. The form itself has not been defined in the add example but would also be defined as a message passed to some system that creates the UI/UX which would expected a message of type UxControl). We could code the usage of our message like this: float result = message.asFloat; // the "makeItSo" as a float primitive int result = message.asInt; // the "makeItSo" as an integer primitive string result = message.asString; // the "makeItSo" as a string primitive Or let's use Add in our configuration: message FormFieldSet ( name "someForm" field "result" source RunAsFloat ( part Add ( left FromFieldGet ( name "someForm" field "left" ) right FromFieldGet ( name "someForm" field "right" ) ) ) ) Let's hook that message up to a ux "button" message Button ( action FormFieldSet ( name "someForm" field "result" source RunAsFloat ( part Add ( left FromFieldGet ( name "someForm" field "left" ) right FromFieldGet ( name "someForm" field "right" ) ) ) ) // properties specific to the layout of a ux element on a form ) and so on. Each message knows nothing about what behavior the messages composed in the properties of the message (100% decoupled) supports. A message oriented language doesn't (can't) have constructs like for loops, switches, if/then/else, etc. in it as those aren't messages if they are integrated into the language. Instead, these are also viewed as messages (first class citizens). A for each statement is also a message: message ForEach ( start FromFieldGet ( name "someForm" field "start" ) stop FromFieldGet ( name "someForm" field "stop" ) action ... ) and so on. If you look at Obj-C, it is really message passing implemented using traditional parameterized subroutines. Smalltalk is a lot more true to it's own nature but they still use methods as an abstraction for passing information between systems (For example, they will refer to #do as method as opposed to a message). I think if Alan Kay was forced to implement Smalltalk by focusing 100% on messages (because he was told he couldn't use parameterized subroutines) we would have had a much different world today. In programming, mental models created through abstractions is everything.
- jasey 12y ago"To make a system sufficiently configurable, you end up having to re-invent a turing complete language inside it's configuration files" This sums it up perfectly, I've had clients say 'oh and it has to be 100% customisable' and I've been like 'it is, it's called HTML, CSS and js'
- nercury 12y agoTuring-complete config files do not sound like proper config files :)
- skywhopper 12y agoUsing DSLs for configuration can be incredibly useful: allowing a single "config file" to respond to its environment and work differently in different contexts. Of course at some point, you're just calling your program your config file. But don't tell Emacs users that config files can't be turing-complete.
- AdrianRossouw 12y agothey can be turing complete. that just looks like lisp. there are other turing complete DSL's too though. Puppet's isn't though...
- mitchty 12y agoYou know I'll say emacs is a great example of how its a great idea to make your "config" files a programming language. I'll also say it's a horrible idea to make your "config" files a programming language. Overall though its hard to argue it doesn't do the job.
- davidgerard 12y agoIt's an antipattern the inexperienced frequently fall into. Just one little extra bit of functionality, and ... whoops! Suddenly, you can program there, so now you will have to program there. Same applies to markup languages. TimBL held HTML back from Turing-completeness for ages, then JavaScript came along.
- jt2190 12y ago> ... whoops! Suddenly, you can program [in the > configuration files], so now you will have > to program there. What's forcing a user to configure a system if they don't need to make changes? Why is it preferable to use something functionally restricted rather than a programming language to configure a system?
- skywhopper 12y agoObviously there's lots of research to be done on the best ways to design programming languages and the best ways to teach them. However, the headline presumes there can be some universal standard of measuring what we can "usability" that's somehow separate from the practical "usefulness" of the tool itself. Tools that do fewer things can be made easier to use that tools that do many things. Turing-complete programming languages can be made to do anything the computer can do, which is a lot. And so there's going to be a hard limit on how "usable" they can be. Not to say we're even close to reaching that limit, but you'll never make a programming language that's as "usable" as a screwdriver, and that's okay.
- joe_the_user 12y agoWell, I'll admit that a rather debatable claim. But article provides reasonably good backup for that claim using the tools of professional user interface design, a field that has become a lot more systematic in recent years. Towards the end of the article, he describes a number of metric which can be used in measurement of programming languages as task-accomplishment tools.
- deleted 12y ago[deleted]
- kingmanaz 12y agoThe "glue-language" philosophy underlying Tcl can strike an optimal balance between usability and power: http://www.yosefk.com/blog/i-cant-believe-im-praising-tcl.html http://www.yosefk.com/blog/i-cant-believe-im-praising-tcl.ht... Shells partition away sophistication.
- dllthomas 12y ago"Shells partition away sophistication." Could you elaborate on this? It sounds interesting, but I'm not quite grokking.
- kingmanaz 12y agoI'll try. Programming doesn't have to be hard. As in speech, the more one says, the less one means. I know shell isn't going to with this popularity contest, but a return to it is what's badly needed in CS today. Instead of attempting to recreate the shell in C# or Java's supplied libraries and subsequently becoming frustrated when interaction with the "outside world" is clumsily accomplished through a FFI pinhole, just use the shell as it was intended: as a lingua franca between utilities. Write what requires prolog in prolog, what requires c in c, what requires awk in awk, etc. Use flat file databases such as starbase or /rdb and avoid data prisons such as MSSQL, Oracle, MySQL, etc. Make all of these utilities return sane return values and spit out JSON formatted output. Finally, tie it all together with shell. If you need a UI, code it as a thin layer in Tk, python/pytk, ansi c/gtk, or, consider pdcurses, etc. Profile your program and find any weak links in the chain. Recode in a lower level language only when needed. Weighing the tradeoffs of adding language features is a sign of a false dilemma; rather than a single bigger or smaller language, what is actually needed are more specific languages which speak to each other through a lingua-franca. Tcl accomplishes this communication through a string representation, Powershell through an object representation, etc. Again, rather than choosing one solution over another, use them all where they work best. This is where Unix got it right all those years ago; Unix isn't just a slightly more stable platform for running today's bloated and monolithic software, rather, it's an elegant system for connecting maintainably-small utilities. The shell glues said utilities together into programs. Such an approach combines the best of high and low level programming, reuse and specificity, tradition and novelty, etc.
- jasonwatkinspdx 12y agoI think it's a massively fascinating question to ask "Why didn't something like hypercard become the web?" And please don't knee jerk some story about some Apple decision making. That doesn't matter. If the hypercard model had the value I think it does, someone else should have surfaced and gained momentum. That didn't happen, and while I don't have the answer for why, I think it would shed some light on why "code as a user interface" for non coders has had only limited successes (Spreadsheets, SQL).
- david927 12y agoFor Hypercard, I think the answer is that, at the end of the day, people will write off any technology that gets "stuck". Spreadsheets are amazing (I have a secret deep love for them) but you can't code with them without hitting a wall of what they can do. SQL and declarative languages are better but still suffer from that granularity issue. [Disclaimer: I work on a hypercard-like declarative language.]
- toby 12y agoIt's arguable that Excel is the most widely used "programming language" depending on your definition. If you've spent much time around certain business professionals, you'll see that they really push spreadsheets to do unexpected things to solve their problems. I've actually wondered why there hasn't been more exploration into visual / declarative programming since it has the appeal of being very easy to get started.
- AdrianRossouw 12y ago> visual / declarative programming ... has the appeal of being very easy to get started Does it, really? I spent the last 2 years building systems that ran off of workflows (as in flowcharts), and I think now that they don't make the big hurdle (capability for abstract reasoning) any easier at all. They are fine to document and communicate things, but as input they are just flawed (except for some very very specific niches).
- toby 12y ago
- 0xdeadbeefbabe 12y agoYes, yes they are. I'm not a programmer, but a user with a refined taste for java--hah just kidding! Clojure isn't so bad though. Java is an interesting interface or programming language because you need an autocomplete editor i.e. another interface to really enjoy it. Don't forget maven and ant for libs and builds. But some people are probably comforted by java ui maybe because it is so structured. Edit: remember ant and maven.
- joe_the_user 12y agoWow, there are many ways to go with this... I would claim that natural language is the most usable and the most powerful user interface. We humans have been relating with it for quite a while and there's no sign of a let-up. And most programming language either contain fragments of natural natural language or can be translated into such fragments. Yet, the author is right, programming languages are "least usable". Indeed, consider SQL was created specifically to be usable like a natural language but it now considered more unusable than even an average programming language. What gives? (I have my suspicions but I wonder what people think).
- thaumasiotes 12y agoUtterances in any natural language are always ambiguous, often hopelessly so. It works out because the speaker and listener are cooperating towards a shared goal; the removal of this assumption of cooperation is why contracts and legal codes get longer and longer over time as they try to deal with the fact that they can't actually specify anything the way they'd like to. The computer isn't like another person, and we'd really prefer to have it do what we say rather than guess what we want and act accordingly. Indeed, we are not yet able to have a computer guess what we want to any respectable accuracy. (Think of it this way. In some languages you can provide compiler hints that say, for example, "this variable will usually be an integer, so please optimize for that". A natural language consists basically 100% of compiler hints and 0% of instructions.)
- joe_the_user 12y agoThe computer isn't like another person, and we'd really prefer to have it do what we say rather than guess what we want and act accordingly. From the point of a view of a programmer, yes. But isn't this kind of the division point between a "good user interface" and a programming language. Lots of user level system are intended so the computer guesses what you want and does that.
- PeterisP 12y agoIn all areas where we need to transmit exact information or describe something in great detail - wether it's 'legalese'/contract language, mathematical notation, musical notation, computer code - we've found out that natural language doesn't fit it well, and chosen to use something less natural and more exact. This is the sign of a flaw - we've stumbled upon the limit in many distinct areas, and ceased to use natural language in them. If you want an architect to describe the builder how large a construction pit should be - you don't want a long description in natural language, you want a very specific diagram; i.e., natural language is not the most usable thing for this scenario. If you want to 'discuss' your computer which file to open, then clicking in a GUI is much more efficient than having the folder contents read to you and speaking the file name - since such technology exists, but only people with severe vision problems choose to use it. In niches where accuracy is important - say, "chat" between pilots and air traffic controllers - you migrate away from natural language by discouraging most phrases (e.g., words "to" and "for") and trying to replace them with domain-specific codenames and "formulas" for saying phrases with very exact meaning. Natural language is a useful general-purpose UI; but for any specific niche we can have a better specialized UI than that - wether it's a controlled almost-natural language, a visual UI, or some specific notation like music scores.
- anon4 12y agoReminds me of the different ways the environment is set up in Windows and Linux. In Windows, when you want to edit your environment variables, there's a simple configuration utility with a list of them, you click and edit and it all takes effect immediately. In Linux, there's a chain of events where different shell scripts are ran in some way at different levels of the bootup process depending on strange and arcane factors, so when you edit ~/.profile that only takes effect in your terminals and not in applications started by the DE, but also not in tmux, because it's not sourced by ~/.bashrc somehow. And once you puzzle out the chain of command and edit everything you have to log out and back in. And when you want to make changes to the global environment, there's /etc/environment, /etc/profile and /etc/profile.d/yourscripthere.sh. Only one of these is the right choice but only for a specific distro, DE and shell combination. Oh, and if somehow you manage to source a script twice your PATH gets duplicate entries in it. Not technically a problem, but it kind of irks me.