Code: n. A system of symbols, letters, or words given certain arbitrary meanings, used for transmitting messages requiring secrecy or brevity.
–American Heritage® Dictionary of the English Language
This is not what we should be writing.
I started thinking that we as an industry need a new term. The reason I say this is related to the Sapir-Whorf Hypothesis, which says that the language we use influences the way we experience the world around us. If we keep referring to what we write as code, we are going to keep writing software that ‘requires secrecy or brevity’, instead of writing software intended for other people to read. Ableson and Sussman nailed it back in 1985, in the preface to the first edition of Structure and Interpretation of Computer Programs, and I am sure they weren’t the first either.
First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.
–Structure and Interpretation of Computer Programs
Let’s take a moment and take a look at another term we use commonly.
program: Late Latin programma, public notice, from Greek programma, programmat-, from prographein, to write publicly : pro-, forth; see PRO-2 + graphein, to write; see gerbh- in Indo-European roots.
–American Heritage® Dictionary of the English Language
That is not bad, as it refers to writing publicly, so maybe, if we start thinking in that sense of the word, we would be okay; but odds are, it has deviated too far from that original meaning in common thought to try to rescue it and bring it back towards that original meaning. If we are going to come up with a better term, maybe we need to pick a term that expresses that we are telling the story of the system; XP talks about Metaphor of the system; and Eric Evans in Domain Driven Design talks about Ubiquitous Language; others talk about modeling the system; but the commonality is that we want what we write to expressive and suggestive. We have a word for the type of writing they describe.
poem: n. A verbal composition designed to convey experiences, ideas, or emotions in a vivid and imaginative way, characterized by the use of language chosen for its sound and suggestive power and by the use of literary techniques such as meter, metaphor, and rhyme.
[French poème, from Old French, from Latin poēma, from Greek poiēma, from poiein, to create; see kwei-2 in Indo-European roots.]
–American Heritage® Dictionary of the English Language
I am not saying that we should all start writing software poetry, but as an example of a word in our lexicon that may have a better fit. I suggest we think about what words would better describe the kind of software we wish we were reading, and then, see how the words we choose change the way we write software. What if we tried writing software poetry, software novellas, or software as the literature of the system, and see how that affects the way we write our software. Do we gain expressivity? Do we encourage others to read what we have written and get editorial reviews? Do we make sure to go back and read aloud what has been written to see if we stumble upon awkward phrasing? Do we take time to go back and try to rewrite what we have just written to make sure it is written well?
I have recently started reading On Writing Well by William Zinsser, and while he is talking about the word processor, I think it relates to writing software as well, since all too often we just move on and submit our writing as soon as we think it is working.
On one level the new torrent is good news. Any invention that reduces the fear of writing is up there with air-conditioning and the lightbulb. But, as always, there’s a catch. Nobody told all the new computer writers that the essence of writing is rewriting. Just because they’re writing fluently doesn’t mean they’re writing well.
–On Writing Well
Right there with you. I’ve long thought that “code” implies “cryptic, secret, arcane”. “Instructions”, maybe?
Yeah, but who honestly enjoys reading the instructions? 😉
Pingback: Dew Drop – July 18, 2014 (#1817) | Morning Dew
The term “code” has multiple meanings that are in common usage.
I never took the word “code” to necessarily mean secret or arcane. Most often, I think it’s used as laws or rules, as in “building code”. That’s even the first definition in the Merriam Webster dictionary, which is the official dictionary used in courts of law in the United States.
Here’s the definitions for the word code, which can be found at http://www.merriam-webster.com/dictionary/code
1. : a systematic statement of a body of law; especially : one given statutory force
2. : a system of principles or rules
3 a : a system of signals or symbols for communication
b : a system of symbols (as letters or numbers) used to represent assigned and often secret meanings
4 . : genetic code
5. : a set of instructions for a computer
Fair point. I would be curious to know how many people think of code in that was, versus definition of 3b from Merriam-Webster, or the one I cited. I have always tended to associate things like Morse Code, encoded transmissions, or decoder rings, as well as terms in the software field like ASCII codes or URL encoding, which tend to associate with the definition I laid out in the post. If you tend to think in the first one much more then definition 3b, or the one I laid out, then it might not have the same impact on the way you write your software if you were to think of code as the other way.
If the essence of writing prose is rewriting, then the essence of factoring code is refactoring. But one must recognize that refactoring comes after factoring. Of course that doesn’t mean we should write bad code always expecting to rewrite it. But we should write lots of code and refactor when we have enough to figure out how best to refactor it.
One thing counter to the refactoring paradigm is the idea that one week sprints (e.g. under scrum methodology) should always result in working builds. Obviously code that is always in the middle of being refactored is not going to build (or run) and endless broken builds results in failure. I haven’t read enough about scrum to know if there are refactoring sprints but that kind of regimentation does not seem appropriate. What kind of prose authors would allow themselves one week timeboxes to rewrite their work?
Often people will say the answer is design patterns or frameworks containing design patterns and auto-generated code. But those would also be an anathema to writers of prose. My best advice is to follow your urge to tear up and rewrite or paint over the same painting like Van Gogh. Do it right when the idea arises, don’t wait until you’ve finished some other function because you might forget. Sure your managers and customers might not be too happy sometimes, but it will be better for them and much better for you in the long run.
One question I would pose would be how much of the time when we write software do we try to make sure it is factored well? Some teams are much more rigorous than others, where software gets written with intent, and others I have encountered were 20,000+ line classes with 5,000+ line methods littered with conditionals and checks that just get added in because someone was just trying to get something to “work”, with some of the paths that were likely dead ends that would never be reached.
I think it gets back to making sure that in either prose writing, or software writing, that we should focus on getting the intent across to those who will be coming back to the software in the future and having to modify it, and understand what, and why it was written the way it was, and to experiment with writing software like we were to write other forms to see what our software starts to look like.
Why would a programmer think about intent any more than a prose author would think about who will maintain their novel after they are gone? It makes sense to maintain the code at the edges, but the heart of well-written code should never need to be maintained.
There are some artists and prose writers with sponsors and deadlines and even great authors have some bad works. The question is: if we are given enough time to refactor, do we refactor? I would pose the suggestion that many programmers do not if the code works because they would rather move to some new challenge. The difference IMO might be the obsessed programmer who puts a much higher priority on refactoring.
Also I would stress that sometimes the only path to a neat new code structure is 5000 line methods. Looking at them once they are created is easier than envisioning the same new code structure on a blank screen. I think what you saw in your 20k/5k example might have been an unfinished masterpiece.
I don’t think we are too terribly far apart on out thinking, although I would contend that a 5k line method was likely never properly factored, or refactored.
I do agree that we should be refactoring constantly and “Boy Scouting” as we are working our on code, in much the same way I hear writers constantly talk about going back and reworking segments of their writing that doesn’t flow or get the point across in the way they intend.
One would hope that the heart of the system would never need to be maintained, but that is assuming a well-written heart to begin with, and that the business needs are not changing causing a new area to become the heart of the system.
I would venture that most of the people who would come across this are more likely to be the types of people who are the ones who would go back and refactor if given enough time, or even to refactor as even if not given enough time, because they see it as part of normal software development.
Also, untouched is the fact that what a change of term might also buy us as software developers, is lowering the perceived barriers to entry and reducing the mystery around “code”, that might prevent others that would be good at writing software because they are caught by the thinking that it is some kind of magic skill.
I would like to disagree with the statement “programs must be written for people to read, and only incidentally for machines to execute”. This rings very nice, sure. But let’s not stand the things on their head for the sake of an extravagant phrasing.
There are machines (I hope we can agree on that one).
In order to do something useful (whatever you put into that word) those machines require software (or whatever you want to call it, but I don’t see a need to invent synonyms unnecessarily).
Therefore, the goal, the purpose, the raison d’etre of the software, or “programs”, if you will, is for machines to execute. This is by definition.
There are other things which are mainly written for people to read. Like poetry, or this very comment. But if there are machines, and if they require software, then that thing which they require is required for whatever it is required, namely, to be executed by the machine. I don’t know how to express the meaning of “by defintion” more clearly.
Sure, it will be nice to make the software readable, and maintainable, etc. This is why we have departed from machine code to assembly to higher level. Alas, when the argument about clarity is put this way, it sounds too familiar, too banal, and hence, not as engaging and trendy as this poetic article. But it doesn’t change the fact that we are writing instructions for machines, and not poetry for people.
I recommend clarity and simplicity in definitions.
No, I have to agree with the OP on this one. What we are writing is a human readable description of what we would like the computer to do. What we bash into our text editors bares absolutely no resemblance at all to what the computer will eventually execute. We are writing a methodology, if you like, something that conveys an idea and explains what we were thinking at the time, and how we tackled a particular problem, which is very rarely the ‘only’ way to do it There are many ways of performing a loop in a text based language for example, but there’s generally only one when it gets down to the silicon. We don’t write at that level.
Our ‘code’ will be re-read by ourselves later down the line, the people who try to maintain our work after we are gone and, more immediately, the bit of software that will actually generate the list of on / off switches that will eventually be executed. It describes, or should describe, our answer to a question, and if it’s written well enough using meaningful names and appropriate commenting, it should remind us, and tell others, how we came to that answer.
‘Code’ is absolutely for human eyes.
Sure the goal is that we get something that the computer can execute, but we are writing the software for our future selves and others to read primarily. As another commenter pointed out, the instructions that the computer execute are different than what we write, as it gets parsed, transformed, optimized, JIT’ed, and translated to machine instructions, which may look nothing like the code that we write. The software we write is rarely intended to be the instructions for the computer to execute, especially when you look at some of the much higher level languages like Prolog or MiniKanren, where the goal is to declare the intent, and constraints, and let the execution engine determine how to get the results, otherwise why are we writing software in higher level languages and levels of abstractions, except for convenience and clarity of understanding for those of us who have to later read the software written?
For many years I have thought about software as art. Some developers work like the kid who can only “paint by numbers” on a pre-printed sheet. Colleges churn out these by the thousands. Others are so abstract that no one can read what they write and see “the picture”. Still others have to use every brush and color they have ever seen or heard about. A true artist is able to select the right tools to create the picture that satisfies the need of the “beholder”. Beauty is in their eye after all. For software, developers should strive to write masterful programs that fulfill the current and (if possible) foreseen needs of the clients and work to make these art-pieces useful to those who come along after them. There are those who painstakingly try to restore art to its original form. Similarly there are maintenance developers whose sole purpose is to keep some archaic application working into the future beyond what it was originally intended to endure and sometimes hook up new work to it to extend its longevity even further. No one envies these folk but many times they are even better at what they do than the original “artist”.
I have some thoughts that have been needing to be formalized along a similar vein of your “brush and color”, and “right tools to create the picture”, that your comment make me think should happen sooner rather than later. 😉
Yeah, let us all program in COBOL, a language humans can certainly read!
Human language is notoriously inaccurate. Our own understanding of what we see and how we explain what we saw to others is also highly inefficient. Human understanding is essential in programming for those in the trade, not so much for others, as they use the product and really in most cases have no need or interest in how the work goes on. For example everyone drives a car, but how many know what an ackerman linkage does or where to find it on their car? What exactly is a MacPhereson strut, anyway? How does the electronic fuel injection system work and why is it supposed to be more efficient than a carbuerator (who knows what that is either)?
You intuitively know this to be the truth, and so it is with programming. However programming has similarities to human languges in the construction of complex ideas, with the exception of actually performing tasks directly as expressed in that language.
Another poster explained that code doesn’t necessarily describe intentional obfuscation, but rather is the rules for expression of a mechanical task. This is a very good explanation, I think.
If you look at a programming language, it expresses in some understandable form a process. Yet that language may be routed to a compiler, which changes the human language to a computer binary code. That code may then go through several optimization steps based on the target processor, and known limitations of the language to remove redundant steps and to take advantage of the knowledge depth of others to further enhance the output. Still, even after all that, a human skilled in understanding the processes and the specifics of the targeted system can actually reverse engineer the code to understand the processes, often without even knowing the exact processor that was targeted. Granted it is easier if you have more knowledge about the source language, and the targeted system architecture, but even without that, the operations can eventually be understood, much like solving a cryptogram.
Therefore I think and it possibly may be only me that thinks this, humans are far more capable, understanding, and skillful that first appears. After all, we did make it this far didn’t we?
I think you have a couple of different ideas in here I want to tease out, and want to thank you for your comment.
First, is that you seem to be talking about the domain language, e.g. MacPhereson strut, and fuel injection system. I agree that we have language around computing constructs the same way mechanics have around car parts/tools. The goal is to be able to express these concepts in our software – even better is for the concepts to be expressed in terms of the business problem our software is intended to solve. The more we can make the software express that intent, and get the software readable for someone who may not understand the implementation language, but knows the domain terms the better.
The second point you touch on is part of my point that what we are writing is intended for use humans to read the software. As you point out, it can go through massive changes to get to what the computer actually executes that it frequently looks nothing like what we wrote originally. Yes, someone very practiced can take that resulting instruction set and reverse engineer it to something more intelligible, but even then, it tends to lose the intent of why, and becomes more about the what.
And we are wonderfully capable, but part of me wonders how much more we could accomplish if we were to spend more effort up front on clarity, instead of having to spend time afterwards trying to mentally put the different parts of the puzzle back together, and reconstruct the WHY of the system, in addition to the WHAT.
There’s a lovely typo in your last paragraph:
All to often we just move on. It’s true that you are writing for two audiences when writing code – machines and humans. Humans can enjoy irony in typos. Machines have no sense of humour, though they sometimes act like they are taking the piss.
Hahaha… Of course there would be… Even after reading it aloud multiple times, and doing multiple passes of editing on my part. ;(
That touches on another topic about Code Reviews being Editorial Reviews that I have been thinking about for years now, and the importance of getting another set of eyes on it.
Thanks for pointing it out. Updated the post, but leaving your comment, and making note that I have updated the post here. 😉
Interesting concept. Compare software engineering to mechanical engineering. Creating an engine by breaking the problem down into distinct parts, defining the system in diagrams and engineering models.
In software the diagrams and models are often overlooked and the whole process is rushed and trivialised by diving straight into coding. Perhaps this is a reflection of the comparative ease in which a piece of software can be created by amateurs without great investment or the pressure of developing quickly without a clear definition of the problem.