Downwardly Scalable Systems
===========================
David N. Welton
davidw@dedasys.com2004-11-14
A lot of thought has been dedicated to scalability in computer
systems. However, outside of the embedded systems arena, most of this
effort has gone into making systems ever larger and faster. I would
like to take the opposite approach, and discuss the implications of
programming languages that "scale down". I choose programming
languages because it's a subject I take a great deal of interest in,
but I believe that the basic ideas here are applicable to many
complex systems that require human interaction.
Good systems should be able to scale down as well as up. They should
run on slower computers that don't have as much memory or disk
storage as the latest models. Likewise, from the human point of view,
downwardly scalable systems should also be small enough to learn and
use without being an expert programmer. It's not always possible to
have all of these things. Engineering is often the art of balancing
several compromises, after all, and at times, it's necessary to add
computing power in order to attain simplicity. However, it is always
a good idea to keep all these targets in mind, even if design
dictates that one or the other of them may be less important.
Naturally, we can't forget the "scalability" part of the equation
while focusing on "simple". It's not that hard to make something
small and easy to use. The trick is that it's also got to be
extensible, in order to grow. The system should be easy to pick up,
but it should also be easy to add to, and should also provide tools
to modularize and otherwise compartmentalize the growing system in
order to not end up with what is known in technical terms as a
"godawful mess". And of course it should still be fun to work with
for the more experienced programmer.
Another part of the balancing act is that often times "simple"
equates to hidden complexity. For example programming languages like
Tcl or Python are "simpler" than C, but this is a result of the
implementation hiding a lot of the complexity from the programmer. In
this case, scaling down from a human point of view conflicts with
scaling down resource usage to some degree, in that these languages
require a bigger runtime, and more processor power to accomplish
similar tasks.
Why scale down?
===============
Ease of use vs breadth of user base
Systems that scale down are not just nice in theory, but have many
benefits. To start with, they have the potential to create more
value. By being accessible to people with less experience and talent,
they allow more people to get more things done than a system
requiring more advanced skills would. The nicest tool in the world is
of no use to you if cannot figure out how make use of it in the time
you have. You may object, saying that not everyone should be able to
use every tool, and of course that's true. We don't all expect to be
able to fly airplanes, and yet they are still valuable to us. The
point is, however, that where two systems are capable of doing the
same job equally well, the more accessible tool is more valuable in
that more people are productive with it.
It's especially important to realize that in some cases, this is more
than just a matter of degree - there is actually a cutoff point,
meaning that some people will be able to do no work with a tool that
is too difficult. So to these people, the complex, hard to use option
is simply not an option at all!
Of course, having more users isn't necessarily a benefit in and of
itself, but if you have a reasonably good user community, it often is
[1].
Disruptive Technologies
=======================
In some ways, systems that scale down may be winners in the long term
even if they don't scale up as well as others. Consider the
definition of "disruptive technology":
A disruptive technology is a new technological innovation, product,
or service that eventually overturns the existing dominant
technology in the market, despite the fact that the disruptive
technology is both radically different than the leading technology
and that it often initially performs worse than the leading
technology according to existing measures of performance. [2]
In short: when the programming technology that scales down is "good
enough", it may open up a field of programming to people who
previously were not able to accomplish anything at all - and give
many more people the chance to write "good enough" code much faster.
Perhaps experienced programmers are grumbling about "the right tool
for the job", and complaining about putting sharp tools in the hands
of novices.
To a degree, they're right. It's best to use hammers for nails, and
saws to cut boards, and to know something about them before taking
them to a board. Computer systems, especially programming languages,
are very complex tools though, and take a lot longer to learn for
many people than learning to hit nails with a hammer. What this means
is that many people find it valuable to be able to do more things
with the tools they know how to use. Maybe the tool isn't perfect,
but if it does a reasonable job of solving the problem at hand, it's
probably a net gain to be able to write the code in the first place.
For example, I once did some work for a client who was, at heart, a
marketing guy who came up with a clever idea for a product. He wrote
the initial code that made it work, and...frankly, it was pretty
obvious that he was a marketing guy rather than a programmer. But -
and this is crucial - he was able to make it work with the scripting
language he used. If he'd had to use something like Java or C that
was over his head, he might not have got his product to the point
where he was making enough money to hire me to clean up his code.
Scaling down doesn't necessarily equate to a disruptive technology,
of course. In many cases it's easy to rejig things just a bit, or
create a better, clearer interface without revolutionizing either
your product or the market in which it resides. Truly disruptive
technologies often create new markets where none existed.
"Case Studies"
==============
Let's look at some real-world examples:
Dr. John Ousterhout, author of the Tcl programming language and the
Tk GUI toolkit realized that scripting languages were a winning
proposition early on, creating a revolutionary way to easily write
graphical applications. This made Tcl and Tk a big success, and they
continue to be very widely used, long after complex, proprietary
rivals such as Motif have fallen by the wayside. Tcl has had some
struggles with scaling up, but in general hasn't managed too badly.
Perhaps Tk isn't well suited to writing a huge, complex application
like an office suite, however the speed of a scripting language is
perfectly adequate for many GUI's. After all, the time it takes you
to move the mouse and click is an eternity in computer cycles.
PHP is another example. While PHP is not a particularly elegant
system, and suffers from some flaws in its approach to simplicity
(it's too tied to the web world, which has limited its uptake for
other uses), it has done a phenomenal job of making dynamic web
programming available to many people who would otherwise not be able
to, or would have to spend much more time to make their code work.
"But what about all the bad PHP code out there?!". Sure - it's there,
but consider that the people doing the ugly programming are almost
certainly not trained programmers. Perhaps they are doctors,
businessmen, artists with deep knowledge of other fields. PHP is
therefore the tool that, through its approachability, makes it
possible for them to do something that they otherwise could not do.
If they are successful in their endeavors, maybe they will attract
"real" programmers who will help them out either because it's a
successful business venture, or because it's a popular open source
idea. In any case, they are better off with an ugly program they
wrote to do the job than an elegant programming language that they
can't make heads nor tails of.
Contrast these languages with Java. Java isn't a bad language,
particularly. It's easier than C in some ways, and certainly safer
for the average programmer, who has to worry less about memory
issues, walking off then end of arrays, and things of that ilk that
in C, not only crash the system, but may create security risks. Java
is fairly resource intensive - it requires lots of disk space,
memory. Worse, it's not something that is easy to pick up quickly for
the 'average guy'. It has a verbose syntax that is unpleasant to use
if you don't know your tools well, or even if you just want to whip
up something quickly. The target for "downwardly scalable languages"
that we're talking about are the individuals who, due to their lack
of experience, are more likely to have bad tools than a veteran
programmer who can play emacs like a piano. Java also makes it
difficult to do easy things. To even get started, you have to have
some notions of object oriented programming, you have to split your
code up into lots of little files that must be properly named, and
you must have a few ideas about packages to even print something to
the screen, with System.out.println("hello world"); Of course, if you
are writing thousands upon thousands of lines of code, some of these
language features that initially seem like annoyances turn into
advantages, and would be sensible rules to follow for any programming
team wishing to keep their sanity. While it's fine to say "it just
wasn't meant for that", perhaps Java could have been made easier for
the casual user. Java scales up to projects with multiple teams and
many programmers better than other systems do. So they have done
something right, but haven't been able (or willing) to make the
system downwardly scalable.
Ok, but how?
============
Making systems that are easy to use is an art in and of itself, and
high quality code doesn't necessarily translate into something that
automatically scales down. Here are some ideas on how to make your
product scale down.
* Make it small, and make it easy to extend. This way, you don't have
a lot of luggage to carry around, and yet you can extend the system
to do more things later. The C programming language is a pretty
good example of this. The Scheme language got the small part right,
but until more recently has had trouble with the 'extend it easily'
bit.
* Make it simple and coherent. Don't give it too many fancy rules.
Make it internally coherent in the way it's used, so that people
can make reasonable assumptions when they see a new extension or
library. They will see patterns in your system which will enhance
their comprehension. Tcl and Python show these qualities (despite
having grown some warts over time). C++ and Perl tend toward the
opposite pole: big and complex, with many rules to remember. You
can always choose to use a subset, but when you think about
communicating functionality to other people, perhaps in terms of
source code, it means that in the wider world, you can't stick to a
simpler set of rules to keep in mind.
* Make it do something "out of the box". It should be easy to get set
up and doing productive things with the system. Complex
configurations with thousands of options are useless if it's
impossible to get a basic configuration working. The Apache web
server requires little configuration to make it serve web pages, so
while it is in some ways complex (configuring it from scratch might
prove quite difficult, infact), it scales down by being useful
right away.
* Given several options, make the common one the default, and the
others a possibility. As programmers, we tend to think that we
should give the user all kinds of clever options. However, most
people are going to use one of the options most of the time, so in
reality, it's often best to make that easy, and add a means of
performing the less frequently used options when they are desired.
Tcl, when it gets things right, does a great job of this. For
instance, its socket command is very easy to use. The default is to
open a socket to a given hostname and port. Then, if you need to
configure things further, such as setting the character encoding,
blocking or non-blocking, and so forth, Tcl provides a command to
configure options. So people who just want a socket get it very
simply, with no clutter: set sk [socket
www.google.com 80]
* Use simple, open protocols. If you have to transmit data, or have
configuration files, make them easy to understand, and simple to
write - by hand or via other programs. This lets people interact
with your system in new and interesting ways, as well as keeping it
accessible to the newcomer.
* Always keep on eye on the future, when you may need to scale up, to
large groups of programmers, for work that requires speed and the
ability to work with large quantities of data. Design the system so
that scaling up is easy, or at least possible.
Conclusions
===========
Naturally, it's not always a good idea to scale down. There are
systems that really do need to be as fast as possible, or to deal
with very complex problems, and trying to broaden the user base is a
secondary consideration compared with these other goals. However, in
many cases these goals are not incompatible, and the simplicity and
clarity involved in scaling down will make for a larger, more vibrant
market for your product.
References
==========
* Worse is Better
* Scripting: Higher Level Programming for the 21st Century
* About Face 2.0
* Scalable computer programming languages
* The Innovator's Dilemma
Copyright © 2000-2015 David N. Welton
From: <
https://web.archive.org/web/20170427181823/http://www.welton.it/articles/scalable_systems.html>