There is a subtle but useful distinction between code and software. Programmers write code: a formal plan of the software, expressing its intent in maximal detail. Software is the end product: in execution it is what the user perceives, interacts with and experiences. Sometimes this difference can be significant.
We may often blur the distinction between software and code, and indeed such a distinction does not always serve a use, but sometimes understanding them as different allows us to separate our own concerns more successfully. Customers and end users are wed to software, software developers to code. The software is the thing that can make a difference to a customer or end user's life or business. It is a (hopefully) functional thing that they interact with and use. Code, on the other hand, is a hidden aspect or counterpart of software. It is more than just the construction of the software: it is the design.
Of course, there is a lot more to design than just code, but coding is not somehow an activity disjoint from design and, as an artefact, code is not somehow a wholly separate thing. It is the ultimate expression of design, in this case based on a formal notation with associated semantics that totally defines, with a high-degree of precision and accuracy, the observable behaviour of corresponding software.
Many complex structures and behaviours can be generated from surprisingly simple rules. The RNA of a virus does not encode explicitly a blueprint of the icosahedral structure that holds its genetic payload. Birds do not flock according to a detailed flight plan. Balancing a pole from the palm of your hand does not involve real-time solutions to various equations. All this complexity, intricacy and adaptability emerge from simple rules. Such emergence is an important consideration in design.
Likewise, the correlation between the size of the code and amount of functionality in the corresponding software is not some simple linear function, if it can be described as a function at all. Measuring code quality by its quantity is a common category error. It is easy to take a requirement and express it using an order of magnitude more code than you would normally require. Experience also suggests that a great deal of code could be replaced by functionally and operationally identical (or improved) code that was at least as comprehensible but smaller in size sadly, sometimes as much as an order of magnitude smaller (and let's be clear, we're talking about decimal rather than binary orders of magnitude here). It would not be an exaggeration to say that for the software that exists and struggles today, there is too much code. As I am fond of noting: less code, more software.
There are certainly times when code needs to be complex, but this does not mean that it should be complicated. And when code needs to be simple, it should not be simplistic. Although well meant, some programmers assume that for their code to be readable and be considered good they must spell out its logic and flow on droolproof paper with the equivalent of kindergarten vocabulary. The resulting code is often dumbed down and padded out to the point of incomprehensibility, achieving quite the opposite result from the one intended.
Keeping up Appearances
Code quality can affect software quality, but not in a way that is necessarily direct or obvious. Software in execution doesn't look like the code that defines it. Code may be the animating but hidden puppet master behind software, but it is not what the users see or relate to.
Code and software have different properties and different audiences. For example, selling a product is quite different to selling its plan. This is not to say that you can't or wouldn't do that, or that a plan might not itself be a product, but it is a different economic proposition. It actually means something different.
The plan also does not look like the product. If I open up source files I see many lines of (hopefully) indented formal notation. When I work with the corresponding software I may see windows, buttons and other things that are not directly visible in the code, even though they are described there. And, given the different audiences for the software and the code, the meaning is once again different.
As programmers we tend to read and often race past the distinction because we see both worlds, frequently crossing the bridge between them. We can read a piece of code and know how it will run. But just because a correspondence exists between code and software does not mean they are synonyms, and just because we can bridge the gap does not mean that the gap is not there.
Visible and Divisible
Code becomes more visible in some cases, but such visibility is more often associated with failure than with the more positive message of the Open Source movement. For example, web pages that generate script errors in the browser, or assertion messages and stack traces that appear in message boxes or on the console as a program aborts. Fault lines can often cut through the illusory world of software, breaking the spell to reveal another imagined world, the world of code.
The perspective of Open Source Software is that, if the code and the software form two sides of the same coin, there is no such thing as half a coin. You get one, you get the other. The code is still an asset, but the software is now a very different kind of artefact: it is still an economic entity it has a direct influence on economics but it is no longer a sellable one. Code remains an asset, but is now in the public, or commons, space rather than a private variable.
There are other cases where the distinction between code and software can seem to fuse. Visual programming tools for user interfaces create a situation where what is worked on by the programmer has a visible, one-to-one correspondence with what the end user will see and work with. However, this is at best a partial blurring. A visual design is a design of the visual aspect. More code sometimes much more is needed to actually realise the software. So, the visual design contributes to the software, but it does not totally define it. In many cases the visual design is also simply the input for source code generation; the visual tool is a means albeit not one to overlook that the programmer uses to achieve that end, so it is often perceived as a precursor to code rather than a codification itself.
In other cases the visualisation has nothing to do with the appearance of the software, and everything to do with the use of an auxiliary modelling formalism to express some other aspect more conveniently. A visual model may be based on something in the problem domain, such as a business process or a chemical process, or it may be something that is more development focused, such as a UML diagram. In neither case is such a codification total and in neither case does the codification equate to the software. Describe it, yes; equal it, no.
Code and software are both informational rather than physical. But while there may be more to code than just source code, code is the definition of software.