Software developers have really crappy tools. If we’re lucky, we’ve got some limited graphical tools for creating user interfaces and some form of rudimentary auto-complete, but our programs still exist in text files, which amount to little more than digital pieces of paper. We want to augment programming languages with new IDEs and tools, but it’s often painful to graft these features on existing languages. What we need are languages built around our tools, not the other way around.
The current best effort for better technical tools in my opinion is Apple’s Xcode, specifically the Interface Builder tool. As the name suggests, IB is a tool for creating user interfaces graphically. Instead of writing code to layout your interface elements, you use IB to position them. You get the benefit of seeing what your app is going to look like as you’re working on it, without the need to stop and rebuild your project with every modification.
Putting aside my qualms with how Interface Builder really works in practice, I do think it’s a great idea. But it’s really not enough, because the interface elements laid out are pretty dumb — you can’t really interact with them much until you actually build the application — which stops pretty short of allowing you to feel how your application really works in practice. You see how it looks with skeletal data, but you don’t get to see how it works.
Another element of Interface Builder are interface Bindings (these are Mac only), which, in theory, allow you to wire up your data to interface elements in your application without having to write any code to do so. Another incredible idea in theory but in practice it’s very difficult to get right, and it’s maddening to debug.
Why are these tools so hard to get right? It’s because we start with a programming language, which in many cases was developed decades ago during different constraints and conditions, and we try to graft modern tools and ideas atop it. In Objective C’s case, the language has its roots in the 1980s (or 1970s, due to C). We’re trying to solder on modern bits to old harnesses, what Wolf Rentzsch refers to as bolting on an air conditioner to a go-kart. Sure, it’s possible, but the effect feels pretty bad. It doesn’t mean air conditioning is bad, it just needs to be installed in the right environment.
Language makers need to change what they focus on. Instead of trying to add nice things to the environment (IDE, Tools, etc) that fit the language, they should instead design a good environment for building software and then design the language around that. Instead of taking decades-old programming language and grafting on an environment, I think it would better to first design a programming environment and then build a language to suit it.
As an example, I’m going to list some things I believe would be good in such a programming environment, and although this list is neither perfect nor exhaustive, I hope it illustrates the point of how programming languages can be designed in the future.
Programmers should be able to see their changes reflected immediately. I’m definitely not the first one to believe in this principle and I’ve made my own stabs at it with the Super Debugger too. But it’s really tricky to get this right with programming languages which weren’t designed with this principle in mind. Imagine how much more flexible the language could be if this were intended behaviour?
The environment should allow for connecting data to graphical representations without the need for excessive glue-code. This is what Bindings on the Mac attempt to solve, but they themselves are glued on. The environment should support this from the ground up so that programmers can easily do the repetitive task of attaching their database or web service data model to a graphical display.
The environment should allow for better traversal of program code than just classes in files. Groups of related functions and methods should be brought together as the programmer is working with them. The programmer shouldn’t have to hunt for method declarations or implementations, nor should they have to hunt for documentation on the functionality. This should be brought to the developer’s field of vision as it’s needed.
Relying on plain text files for source code drastically reduces the flexibility of the programming environment. Instead, the files can be stored in a smarter format as required by the programming environment. We already rely so heavily on our environments as is, as we have long method names which require auto-complete and stub/generated functions that we can never remember. And yet we feel shameful when we use a plain-text editor but we can’t remember how to code without the IDE. Why not instead embrace the IDE and not be ashamed when using a language-ignorant text editor?
Features like auto-complete are great, when they work. But imagine how much better they would be if the language was designed from the beginning to support them?
These are just examples and many of them have existed as ideas for decades at this point, neither of which is important. The point I’m trying to make here is that whatever the principles of programming environment design are, it should be those principles which dictate how the programming language should work. We should strive to figure out the kinds of tools developers need to create exceptionally powerful programs, and then design programming languages to enable those tools. It doesn’t mean the IDE has to be written in the new language, but just that it should be written with it in mind.
Software is currently the best medium we humans have to express our explanations and explore our ideas. And yet the way we express these programs is limited to what are essentially digital versions of pieces of paper. It’s time we start building better ways to express ourselves with interactive media, and that means building the backbone language around the environment in which it lives.
If you find this idea intriguing, you should definitely come hear me speak at NSNorth in April 2013 in Ottawa. It’s going to be the start of something great.