I realized something curious today. As programmers, we use the same tools for two very different tasks, reading code and writing code. Our IDE’s (or text editors), display only one view of a program’s source code, and it is universal. But the requirements for reading code and writing code are very different. When writing code, programmers universally appreciate succinctness. It’s often over emphasized because for most programmers writing code is the fun part, so making it as fun as possible is top priority. But we know eventually, we will expend a great deal more effort and time reading that code. Succinctness has value for readability, but it has limits, which don’t necessarily apply to writing code. It may be easier to type “i”, then “index”, but is it more readable? So our parameters for reading code are different. When reading code, we should have more information available then we are required to write. Intellisense is a partial example of this vision. Not only does it reduce what you need to type, but insures later when reading, you will have more information available. Intellisense is not enough however, we should have IDE’s that show us, or allow us to see, implied characteristics that compilers can compute. For example, I really appreciate OCaml’s ability to infer types, signatures and such. When using a prompt, you get to see results of your declarations. But once you go into an IDE, a lot of that information is missing, which is silly because that information is even more important when reading in an editor than writing at a prompt. I’d like to see that information, and more displayed in my edit/read window without having to hover, click, etc. I’d be ok with a switch to go from read to edit mode if that’s what the interface requires, but I think it’s critical that we stop thinking only about the writing, and begin putting more thought into reading. One of the things you’ll hear the most from Ruby fans is they like how readable the language is. In many ways, I’d certainly agree, there is a lot other languages can learn from Ruby about readability. But there are some chinks in the armor. I’ve been picking up Ruby lately, and I’ve been frustrated by the lack of support for things I take for granted in Java or C#, such as Intellisense/AutoComplete. Because it is a dynamic language, which doesn’t really know the type of variables until runtime, tools often don’t know what the author intended when he wrote a set of code. In the long run, this will be a limiting factor for most dynamic languages. One could design a dynamic language with a full type inference system, but that is quite difficult and requires compromises to the dynamic language ethos, so they aren’t. Without this information, IDE tools will be less functional. But, dynamic languages are all about the language. Everything evolves from the language, and it’s been this way ever since LISP. But today, to make a great development environment you need to look at more than just the language. First, you should consider your API as well. This was one of Java’s early strengths. It had an excellent well-crafted API designed alongside the language. This was contrary to the C++ development model, which created multitudes of APIs separated from the language, without any strong common base. As well, you should consider the IDE. This is a recurring strength of C#. The design of C# took into account Visual Studio and the .NET framework and vice versa. C# lends itself to preparsing extremely well, and as a result, features like Intellisense, Refactoring and Class Browsing are highly supported. .NETs assemblies and metadata likewise help support these features extremely well. I recently read Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, and the most interesting part of the book were the annotated comments. Besides being open about mistakes made in the design of the .NET Framework API, it also makes clear the amount of thought that went into optimizing the API for use with the IDE. By considering features like Intellisense in the design, Microsoft could design the framework to make it easier for developers to find information fast. It’s amazing how easily and how commonly developers dismiss the IDE from the equation, even when talking about usability. Take this article, “Are programmers people?” as an example. But the IDE is becoming more important with every passing year. Intellisense, Refactoring and Unit Testing are just the tip of the iceberg. Smalltalk was ahead of its time in some of these areas, and coincidentally was the last widely known language with an integrated IDE before .NET. But automation of these capabilities requires information, and this is the Achilles heel of dynamic languages. By their very nature, they have less information available when the IDE needs it because they don’t intend to figure these things out until runtime. Static types are metadata, and that metadata is incredibly valuable to pre-runtime tools. I respect dynamic languages. Dynamic languages have done some great things, but most of them are doable in static languages as well. The recent surge in interest in dynamic languages, especially Ruby, has demonstrated the value of features neglected by mainstream language developers for far too long. Even after this, dynamic languages will have their place and many unique advantages, but I disagree strongly with anyone who thinks static languages are a dying breed. Metadata will become more important in so many ways. What we will be searching for in the future are ways to give our tools more information, with less work. Settling for just providing less information not only cheats tool developers, but also cheats ourselves later on when we want to read our code. I imagine a day when give us succinct methods for indicating intent, validate that information, and suggest safety while still allowing freedom. In addition to helping write safer code, or allowing secure systems to validate it, I also imagine this data helping us to maintain our code by providing more information and insight to the maintainer than the original author explicitly typed out.
Saturday, August 12, 2006
IDEs, Dynamic Languages and the Importance of Metadata
Labels:
.NET,
general programming,
ideas,
language design
Subscribe to:
Post Comments (Atom)
1 comment:
Smalltalk is in many ways similar to Lisp. The ideas of Lisp have been applied to Smalltalk and the Smalltalk ideas have been applied to Lisp. When Interlisp-D got developed the team exchanged a lot of ideas with the Smalltalk guys. They were using the same hardware. Booch at an EclipseCon: 'For those of you looking at the future of development environments, I encourage you to go back and review some of the Xerox documentation for InterLisp-D'.
In many Lisp systems the IDE and the runtime are integrated. Since you have ALL the information about a program available, your IDE can query the runtime for it. The runtime is the database and the compiler records all kinds of information. Where is your code used? The arguments? The documentation? The author? Where is it located? All this will be answered by the IDE. InterLisp-D had syntax-directed editing, fuzzy completions, spell corrections, code database management, and so on. All that stuff is long known in the Lisp community. When you are on a Lisp machine and you file a bug report for a code class or function, it knows to which system it belongs and the maintainer of the system.
Lisp IDEs don't have less information available. There are some IDEs that have MUCH more information available than most IDEs. ALL data by default carries the type (the class). On more advanced systems all output to the screen records these types. So you can go back from the output to the object, to the class, to the source with a click on the screen. Everything you see in the IDE are live objects and you can query them and change them all the time.
You may want to read the documentation of InterLisp-D, which is available or for example this old introduction to Genera:
Genera Concepts
Post a Comment