
Writing Good Code Is a Lot Like Writing Prose - akras14
https://www.alexkras.com/writing-code-is-a-lot-like-writing-prose/
======
dayjah
This is an interesting read. The structured approach to writing (code or
prose) with intent is surprisingly rare among developers of various skill
levels in my experience.

One of the key pieces of advice I give to new recruits is "write a paragraph
about your intent, what do you want this code to do?". This, it turns out, is
non-intuitive for folks as it requires first understanding what is there (OP
notes this well) before jumping into coding. I think the root of this is that
you're paid to write code and you want to impress right from the start.

Thus I found it very interesting when a few Q4's ago I was tasked with
creating a new recruiting site for engineers (
[https://engineering.twitch.tv](https://engineering.twitch.tv) ) to better
understand our culture. The central focus of this site was to be a series of
blog posts which highlighted core work that had recently taken place. My job
quickly became editor in chief; working with engineers of various levels to
understand what they've been doing, what was cool about it, and get them
writing about it. Seven blog posts were identified and I made calendar events
to check in seven days from then to read drafts... seven days later no drafts
existed. As I dug into this it was apparent that they'd all assumed they could
jump into the writing prose much like they do code, they all remarked that
writing prose is actually really hard. I provided a template of my own pieces
over the years and by the following quarter we had three pieces written!

I credit TPW for giving me words to describe this to engineers (
[http://tom.preston-werner.com/2010/08/23/readme-driven-
devel...](http://tom.preston-werner.com/2010/08/23/readme-driven-
development.html) ) and my high school English teachers for giving me the love
of words!

~~~
joshuamorton
>I credit TPW for giving me words to describe this to engineers (
[http://tom.preston-werner.com/2010/08/23/readme-driven-
devel...](http://tom.preston-werner.com/2010/08/23/readme-driven-devel..). )
and my high school English teachers for giving me the love of words!

This so much. I find that my strong liberal arts education in high school has
made me a much better developer. Things like meter and pacing are quite
applicable to writing code, and like you I have only my high school English
teachers to thank for that.

So many of the processes around writing (good) code are similar to those
around writing (good) prose, it amazes me that non-technical writing and
literary analysis aren't more strongly preferred.

------
newman8r
I think the more useful side to this is that the path to understanding a
codebase or library is in some ways like understanding a literary work.

It takes some time, rereading a bit. discussing it with other people who are
reading it, making the right amount of notes in the margin, consulting the
dictionary when you don't understand a term. If it's in a language you don't
know, you can translate it slowly, but knowing the basics goes a long way.

I like this way of looking at it because it has more to do with gaining
understanding than with promoting some semantic style in regards to
documenting

------
altotrees
I studied both English and CS in a hybrid program in college. One of the
things that appealed to me about writing great code is that it did parallel
good writing. The process of writing, especially a paper or a longer thesis
relies on logic. There have to be clear bridges, or segues between sometimes
disparate thoughts, connecting them.

I find when I am writing code, I try to use the same principles. I don't want
anyone to look at two isolated pieces of code and think "what the hell, these
don't even belong in the same universe, let alone the in same repo." Whether
through comments or just good self-documenting code, I want things to connect
in some way.

Jeremy Ashkenas made the connection in a piece of his writing about
coffeescript as well. Kind of an ah-ha moment for me.

------
jcbrand
I agree that one should strive to make good code human-readable and I often
also try to use names in a grammatically correct way (to make reading easier).

However, this article leaves me wishing he'd show examples of what he's
talking about.

I'd like to see his code to determine whether it _reads_ more prose-like.

~~~
matt4077
I'll give my personal pet peeve as an example: abbreviations.

When I want the constant for the user's language, everyone knows they're
looking for LANGUAGE, in principle. And long identifiers aren't quite the
problem any more with autocomplete. But some library- and language authors
insist on saving 4 bytes by naming it LANG, or even just L. Or they somehow
end up with this abomination:

    
    
        > locale
        LANG=en_US.UTF-8
        LANGUAGE=
    

There are better examples where more variations can be found in the wild. And
there are some abbreviations that somehow just feel terribly ugly to me, but
I've apparently succeeded in erasing them from memory. They sometimes remind
me of people who use a plus sign instead of the word "and"–it betrays a
certain lack of respect for the language,

------
swiley
Really any creative task is the same: writing music, writing software, writing
prose.

You have your primitive ideas for some chosen rules, chosen such that the
desired product is a valid idea in those rules. Then you combine your ideas
through concatenation and composition to get more complex ideas. Sometimes you
realize your rules aren't quite right so you change them some. You keep doing
this until you have a big idea that fits your definition of a "solution"
(whatever that means) and then you're done.

------
matt4077
Editors really need to improve their support or comments. Currently, they're
even deemphasised in some color schemes (looking at you VSCode).

I built a prototype for an Atom extension a while back that rendered Comment
blocks with a markdown parser, inline, right in the editor.

I'm hoping that the VSCode team gets around to implementing the extension
hooks necessary to implement this at some point, since I've switched away from
Atom.

~~~
Cacti
It's bizarre that we're still marking up code with comments like it's 1960. We
need some sort of standard to include comments in code like footnotes, margin
notes, and so on, that allow us to better explain what is going on without
changing the actual readability of the code.

It would require us to move away from strict file-and-text-editing as the end
all of programming, which makes many uncomfortable of course. And you get into
lock-in issues.

~~~
dragonwriter
> It's bizarre that we're still marking up code with comments like it's 1960.
> We need some sort of standard to include comments in code like footnotes,
> margin notes, and so on, that allow us to better explain what is going on
> without changing the actual readability of the code.

Actual comments already do that if the editor hides them by default; you don't
need different syntax or abandoning pure-text representation, just the right
editor features to do what you want.

------
amelius
Or, in other words,

(ROOT (SINV (VP (VBG Writing) (NP (JJ Good) (NNP Code))) (VP (VBZ Is)) (NP (NP
(DT a) (NN Lot)) (PP (IN Like) (S (VP (VBG Writing) (NP (NN Prose))))))))

~~~
zappo2938
I hate when I read other people's code that has scores of characters on the
same line. My code is less prose and more poetry. I treat each line as its own
idea.

~~~
Toenex
I much prefer the poem analogy. My favourite code almost appears to dance
around in my mind.

~~~
TeMPOraL
My attempt at parediting original example into poetry:

    
    
      (ROOT
       (SINV (VP (VBG Writing)
                 (NP (JJ Good) (NNP Code)))
             (VP (VBZ Is))
             (NP (NP (DT a) (NN Lot)) (PP (IN Like)
                                          (S (VP (VBG Writing) (NP (NN Prose))))))))

------
hashkb
A code comment is not like an intro paragraph. Comments are second class
compared to code; see any code base. Of course they don't actually do anything
except confuse humans, partially because they have no defined syntax or
grammar, and partially because most programmers fail to maintain them as they
change code.

~~~
skybrian
Even incorrect comments are enlightening rather than confusing if you read
them with the right mindset.

From the code you can tell what the program actually does. From a comment you
can get some idea about what the authors intended, at least at one time in the
code's history.

------
Dirlewanger
Don't really understand this article. It just takes the writing process and
inserts bits about writing good code into it. If anything, good code should
read like Hemmingway and nothing else. And as such, not all good prose will be
as dry and concise.

------
gbrown_
Whether you use it or not the Illumos code base[1] is one of the most well
written I've seen in this respect.

[1][https://github.com/illumos/illumos-
gate](https://github.com/illumos/illumos-gate)

~~~
thedonkeycometh
Can you explain further?

~~~
gbrown_
It's very well commented and often flows like prose. Many files start with
large block comments outlining intent, design, and implementation. Further
code is then annotated as appropriate. The libumem stuff is a good example.

[https://github.com/illumos/illumos-
gate/blob/master/usr/src/...](https://github.com/illumos/illumos-
gate/blob/master/usr/src/lib/libumem/common/umem.c)

------
pechay
I can see some merit in this, a story will often reveal the problem better
than cold analytics, but I have to say I still think the common approach of
defining the objects and then the actors is going to get a better outcome.

~~~
mannykannot
Those objects and actors come initially from a story, and how you tell that
story may affect how well you define them.

Defining the objects, the actors, and their interactions is part of writing
prose, but there is more: you have to present them in a logically consistent
manner, and furthermore in such an order that the reader is not confronted
with an idea she has not yet been prepared for. The way that the components of
a program are assembled has analogous consistency and ordering requirements.

Writing a program is a bit like writing a specific form of prose: an argument
for a proposition. In the case of programming, the proposition is that the
program will do whatever it is that you require of it.

------
torrent-of-ions
You mean Knuth was right?

------
chrismorgan
And good code will _contain_ a lot of prose.

~~~
coldpie
By "prose" here I guess you mean comments? Strongly disagree. Most code should
be self-documenting through variables, well organized functions, etc. Public
APIs should contain lots of documentation, but the actual implementation code
should be sparsely commented. Otherwise you now have two "code bases" to
maintain.

~~~
chrismorgan
Public API documentation is very definitely a part of what I was meaning; but
most code can also benefit from liberal explanation of _how_ and _why_ certain
things are as they are.

Many comments that are written could be better handled by restructuring the
code they reside in the midst of, but many code comments _can’t_ be done
otherwise, and to attempt to do otherwise would be convoluted.

To take an example of some code I wrote today:

    
    
      // Object.values is from ES2017 and Overture uses it; anything that has it will
      // have the other things from ES6 that we need, so we don’t need to add the
      // weight and load time of core-js for them. Browsers that thus need core-js
      // are approximately: IE, Safari≤10.0, iOS≤10.2, Chrome≤53, Firefox≤46,
      // Edge≤13?. No up-to-date browser needs it (for better or for worse).
      if ( !Object.values ) {
          dependencies.O = [ 'core-js' ];
      }
    

This comment is about explaining _why_ a thing is as it is. Self-documentation
by naming tends to only take you as far as _what_ ; for a case like this, it
would have led to something like this:

    
    
      var needCoreJs = !Object.values;
      if ( needCoreJs ) {
          dependencies.O = [ 'core-js' ];
      }
    

This wouldn’t have explained _why_ core-js is needed—or why I considered
Object.values a suitable test.

I tend to draw a distinction between single-line comments which are only
sentence fragments, and _prose_. Prose is beautiful in code.

A part of the illumos codebase was linked to elsewhere in these comments, and
I think it satisfies my point also: [https://github.com/illumos/illumos-
gate/blob/master/usr/src/...](https://github.com/illumos/illumos-
gate/blob/master/usr/src/lib/libumem/common/umem.c). 600 lines of
documentation up front is more than I’d typically expect, but it’s well done
in this case. After that, there’s liberal application of explanatory comments
where they can help.

The rustc borrow checker is another example that I like:
[https://github.com/rust-
lang/rust/tree/master/src/librustc_b...](https://github.com/rust-
lang/rust/tree/master/src/librustc_borrowck/borrowck). What is now README.md
used to be somewhat shorter (though still long and involved!) and in mod.rs.
Look at both files. The documentation here is _all about_ implementation
detail; without this extensive prose, I’d say: good luck understanding
borrowck. With it, it’s involved, but quite attainable, and you can approach
the code without needing excessively deep and intricate understanding of
everything about rustc.

Comments can be done badly, but they can also be done really well.

~~~
coldpie
Sure, of course it's needed sometimes. But I was disagreeing with this
statement:

> And good code will contain a lot of prose.

I disagree. Good code can also contain no comments. It's not an either/or
thing.

~~~
chrismorgan
I will adjust my position to this: non-trivial good code will contain a lot of
prose.

------
HugoDaniel
Nice post! I would add that some prose reads like poetry. Some poetry is
abstract and unreadable :)

------
weego
Writing something is like writing something. what an insight.

