Summary: The value of types is documentation/guidance, not performance. Thus type systems can provide escape hatches without compromising their value. Also, covers uses of Plug-ins and advice on how to build a developer community.
My programming side has been quite quiet out here in blogland lately. One of the reasons is I’ve been working on something I’d like to share, but the company I work for doesn’t quite feel comfortable with that. It’s not world changing, since it’s still fairly domain specific, so I think the concern is a bit overstated, but it is interesting and as such has consumed a fair bit of my programming thought time, which leaves me with little to share.
Luckily for me, Yegge’s recent post, dances around a number of my favorite topics. Like type systems (way down at the end). I agree with some of what Yegge says here, but I think he’s missing an opportunity I mentioned in Suggested Type System. Steve says “that you need escape hatches”, and ML systems aren’t used because they “don't have any holes”.
Despite being desperately close to the concept, he continues on to continue to advocate that static typing is inherently flawed and that the only thing holding back dynamic languages is a lack of execution or community mismanagement.
The problem is typing is not simply about turning software into hardware. That is one common use, and oddly he recommends it as the usefulness of Common Lisp type annotations. Personally I’m starting to hate that Common Lisp feature because it distracts so many people from the other purpose of types, the purpose that has far more value and reason.
The value of types that will always remain is they can be used as guides. This purpose has been perverted in varying degrees in many static languages when the performance promise is held out. Despite both qualities relying upon type data, they are not complimentary. In some cases type information is dropped from runtime/compiled code in the name of performance.
When runtime type checking is dropped you are faced with two horrible choices. Either you must find a way to remove all possibility of inaccuracy before runtime, or you must endure the possibility of catastrophic failure. The first system choice inevitably leads to systems ML like systems that attempt to describe every possibility and to remove all the holes. Like Steve points out, it’s a nice concept, but rather unworkable for real development. The second choice leads to C++ or worse.
Java, for all its flaws, did do something right by bringing the runtime type checking back and most of the type data. Unfortunately, the escape hatches were not planned well and in many cases intentionally neglected. There is some change happening here, but like the problems in the dynamic area, the community makes it difficult to effect change.
My choice for direction is a language that encourages types and provides all the guidance they allow for, but at the same time provides all the holes you need and all the holes you want. But you should have some clue when you’re passing through a hole. You shouldn’t simply be tossed into a piece of Swiss cheese. The goal should be to design a language where there is less reason to use holes, not a language that simply has fewer holes.
Plug-in systems
Yegge doesn’t specifically mention the connection between plug-in systems and type systems, but the implied connection is there. It’s about extensibility and flexibility, and the value of a plug-in system is hard to deny, there have been far too many great and important systems that relied heavily upon their plug-ins.
Operating Systems are essentially big plug-in systems, as each application is an extension of its own. But beyond that idea, operating systems always have numerous other finer grained plug-in systems. Drivers, Context Hooks, Services, etc.
But plug-in systems are difficult. Windows has been criticized and lauded for its extensibility, which for good or evil is extremely extensive. UNIX has always had a history of extensibility, which undoubtedly OS X has inherited, although it’s not very much part of the Apple philosophy.
Windows is somewhat of a special case, however, as its popularity has brought the evil side to the foreground as security exploits often took advantage of the extensibility, and the number of poorly written pieces of software that caused problems through improper use of extensibility caused non-vigilant users problems.
But most systems don’t face a similar quantity of misuse and as the runtime check becomes more prevalent it becomes easier to limit the possible negative impacts. It’s still quite easy to create a problem which a malevolent attacker or incompetent partner could misuse, but at least it doesn’t require a herculean effort.
All that aside, a plug-in system that is adopted by a community can singlehandedly insure the success of a product. FireFox’s strongest feature in my opinion is the add-on community. Internet Explorer has an add-on system as well, but it’s not as well adopted by the community.
Community Adoption
But how do you insure your plug-in system will be adopted by a community?
Well, you should make it easy to use, but what does this really mean? For plug-in systems you need to recognize that you have two groups of users, developers and users. Most companies have a good idea who their users are, but who are the developers? In mass market products or developer tools, like web-browsers or IDEs, the developers are a subset of the users, but for more specialized products this might not be the case. In more specialized products, developing a plug-in community requires going outside your user base to find developers.
But why would someone outside your user base develop a plug-in? When the developer is part of your user base then you can rely upon self use as motivation, but if they are outside you need to provide another motivation. The simplest substitute is money. For mass market products, money is also a good secondary motivation. So you need to provide a way for your developer community to monetize their effort.
Once you’ve identified who your potential developers are, you need to define easy to use in their terms. If your application is a development tool, you can expect your developers to be highly skilled developers, experienced with your tool. With a mathematics tool, you can expect your developers to be skilled in a field closely related to development, but they may not be programming every day. With a web-browser, your developers are probably more familiar with JavaScript than other languages.
Questions like these help define what easy to use is for the developer, but what about the user? More than anything, users want to have confidence in their plug-ins. Although some efforts in this area can be contrary to the goal of developer ease of use, you need to provide the user some security against malevolent or incompetent plug-in developers. Things should fail gracefully if a problem occurs. Diagnosis should enable identification of which plug-in is the source of problems when they occur. Depending upon how large your community is, and how mission critical your application is you may need to control the channel into your system and only allow approved plug-ins. Or, you may support certified and uncertified plug-ins.
An area where both developers and users can benefit from is by making it easy to find and install plug-ins. Developers benefit because it’s free publicity, and the benefit to users is obvious. Automatic updates are important as well, as it make maintenance easier.
At the same time, you need to think a little bit selfishly too. You’re still going to need to support your customers, so you need to insure that you have the necessary information about plug-ins and their effects available to your technical support people.
I could go on, but unfortunately I must go now.
No comments:
Post a Comment