Let's begin with WhatIsAComputer. It's a meta-machine that can become other machines. Examples: typewriter, photocopier, camera, piano, etc.
Definition: Software is the design for a machine that a computer becomes.
So programming is the act of producing a design. (Compare with other software analogies: construction, manufacturing, composing)
Being a design means:
Note: As observed by a very junior assembly programmer 20+ years ago, and DouglasAdams more recently, a computer is a modeling device. With it, one can represent just about anything.
- hard to estimate. it's not a rote procedure and can't be managed like a manufacturing process.
- it's intangible because a design is one step removed from the actual object it represents. It's hard to look at a design and know when its finished.
- Testing and debugging are design activities - they are the equivalents of design validation and refinement in other engineering disciplines. They can not be shortchanged. (from WhatIsSoftwareDesign)
Aside on Design vs Making (see JackReeves
' paper in WhatIsSoftwareDesign
Design vs Making. Programming is design. The making stage is the compile&link&deploy which is a manufacturing process. Unlike most manufacturing, this one is very very reliable. Contrast this with the creation of a physical object: a pair of pants. A designer creates a design, chooses colours, fabrics, buttons. Then a different group of people take the design and manufacture the pants. This making stage requires a lot of skill, but not design skill. In software, the making stage has been deskilled down to virtually zero.
Some programming is making -- such as converting pseudo-code into code. Pseudo-code is so close to actual code that the decisions involved are minor. Here, the programming process involves upstream architects produce design documents that to some extent are
Attributes of Software
Software is invisible
. You can't see code, except a screen full at a time. And just to look at it is meaningless -- you need to mentally execute it to really see
it. (ex. you inherit a pile of code - is it finished? does it work?). All you can see from software is its effect on the world (pixels on a screen, sound, robot movements, data on a network). This is why testing is so central to producing software; executing it is the only way to make it visible.
Software is fragile
. Was it EWD who said software requires a new type of common sense that people haven't yet developed? A single wrong bit in a billion bit program can break the entire program. This makes software incredibly unforgiving. Physical objects fit together with tolerances. There is no tolerance in software unless you build it in.
Software is recursive
. Software is written on top of other software. A programming language is software, as its its runtime library, frameworks, components, and other libraries. The problem this causes is that these building blocks are often not reliable (hmmm reliable manufacturing with unreliable components).
Software is dynamic
. It's a fast moving industry. Hardware is constantly changing. Operating systems change. A piece of software is therefore constantly under risk of breaking because of changes to its dependencies. Another problem with change is that solution tradeoffs keep changing because hardware is changing at different rates. It's now faster to read a small file of bytecode and compile it on-the-fly than to read a large file of machine code (this is due to differing rates of improvement in CPU speeds vs I/O speeds). It's difficult for the software profession, only forty years old, to build up a standard practice when the problem keeps changing. 1960: make it work + make it fit in memory. 2000: make it work + make it secure from network hackers.
Software is reusable
. Software is information and therefore as easy to copy and distribute as any other digital data. This is true for both source and binary versions of software.
Software is uniform
. Almost all software is text and can be created with a computer, an editor, compiler, and debugger. Contrast this with a car which requires many materials such as steel, rubber, plastics, glass, paint, electronics, and leather. Each has a different manufacturing process and requires different tools. The assembly line for a car is hundreds of different machines. The "assembly line" for a software project is many similar machines.
Software is an Infinite Space
. Software's biggest strength and weakness is that it's a blank slate. Most programmers can't resist the urge to ride out into the frontier and build their own city.
I read a couple articles making some vague references about making software, especially OSes, less fragile using rules systems and AI techniques. Any idea what they could have been talking about? Fault-tolerance and self-healing systems seem to be active areas of research these days. There was a fabulous article about software techniques used by Lucent switches to achieve five nines reliability. Patterns such as FoolMeOnce?. I'll try to find the original URL but try this http://hillside.net/patterns/definition.html.
Hardware is the stuff you can kick.
Software is the stuff you can only yell at.