Friday, November 22, 2019

On Writing (Code)

Introspection into my own process for making software has led me to believe that writing prose and programming are fundamentally the same. This was further highlighted for me when I read Stephen King's On Writing. I saw interesting parallels between the way he likes to work and the way I like to work. Also my code is a horror story.

King likes to write a first draft as quickly as possible. He does this to get the story out. He doesn't worry about character development or even holes in the plot. Those he will fix up in the second draft. The first draft is about getting onto paper the good bones of a story. Then he lets the first draft sit for a couple of weeks.

When he can come back to the first drift and it looks familiar but not quite—like it was written by his doppelganger—then he has enough distance to make the second draft. That's where any story issues are fixed and things are smoothed out and tightened up. His goal is to make the story 10% shorter.

When I write code:

  • I like to write code breadth-first so I can see all the moving parts and that everything fits together.
  • I like to let it sit for a couple of minutes, or hours, or days—whatever I can afford.
  • I like to smooth things out and tighten things up in the second draft—things like function names, refactoring, etc.

Maybe writing code isn't exactly like writing prose. Maybe it's more like knitting or woodworking or cycling or solving crimes. I think part of the reason that programmers tend to see their work in everything, is that programming is really just process for solving problems and giving form to thoughts. Those skills can be applied to many different domains. Maybe in that way it actually is more like writing than other hobbies?

At least I didn't say that programming is like gardening. I actually appreciate gardening as a hobby because of the fact that it is entirely different than making software!

Tuesday, November 12, 2019

How to Survive Life Undamaged

How does one survive life undamaged? Seriously... if you figure it out let me know. I particularly mean self-inflicted damage. You can't guarantee anything about how other people act or think.

Here is what I have tried (am trying):

1. Be willing to listen to others.

You don't have to listen to everyone, but be aware that you risk losing valuable perspective and insight, even if it is insight about how not to do things. You should probably be willing to listen to some people that you have shut out. If you are not uncomfortable, then you are not growing.

Everyone has a story. You can either imagine a person's story, categorize and label them, and treat them as if that story is true, or you can actually listen. You can listen to what someone believes while thinking about why they're wrong and how you will show them, or you can try to inhabit their space and see the world the way they see it. You don't have to stay there, but you will take lessons from it.

2. Be skeptical by default.

To listen to others and inhabit their space does not mean uncritically accepting their ideas. You can be empathetic, you can entertain an idea, without being swept away. You can also question if a person is wrong without imagining they are your enemy.

If some idea pushes through your skepticism, accept it. It is OK to move a little closer towards an "opposite" view.

3. Don't try to convince everyone.

This can be particularly painful when it is someone you respect and/or love. It may take time. Or it may never be. Life is sour sometimes. Don't make it more sour than it needs to be.

If you are skeptical by default, then maybe others are as well? If you are listening to others and inhabiting their space, then you must know that it will not be easy to convince everyone. You can let that bother you. You can turn it into an obsession, or you can focus on the good (what little you estimate there to be) and seek friendship.

These are three things you can try. If you refuse to listen to others and make it your life goal to convince everyone how they're wrong. You will have a life filled with stress and bitterness. Or you could listen--critically--and seek friendship over rightness.

Wednesday, November 6, 2019

Beyond Techniques

I firmly believe that writing software is a creative act. I believe that a construction project---or any other linerally presenting process---is the wrong analogy for software development. A much better one is writing prose, which is a process of writing and rewriting and rewriting, and sometimes throwing it all out and starting over. In the same way a software engineer names and renames, factors and refactors, etc., then extends the functionality by doing it all again. This all has to fit into the larger code base in a way that makes for a consistent whole. This requires judgement and taste.

To come at the argument from the other side, if you spent your days rewriting the same code over and over, then you would split it into more generic functions and perhaps a library. If you're solving the same problem that someone else has solved, then you would just reuse their software. This does in fact happen, and yet software engineers still get paid to work, and the value they generate is in the new stuff that requires creativity. Sure, there are some inefficiencies that mean people rewrite software that they could have just reused, and you could argue that the new things to be done are increasingly marginal, but on the whole software engineers would be out of work if there were not new things to create. Ergo writing software is a creative act.

The next reasonable question is: how does one create? I believe that fundamentally, and on average, one cannot directly induce creativity. This isn't entirely satisfying. I wish creativity was a predictable, mechanical process. Is it possible to discover and categorize tools for thinking? I'm still exploring that. Here's an example: to get a fresh perspective on your problem think not about how to solve it, but how to avoid failing to solve it. Instead of trying to figure out how to build a stronger bridge, maybe you'll gain insight by considering how to avoid building a weaker bridge. This technique for finding fresh perspective...does it not make creating into a predictable, mechanical process?

I actually like techniques. I believe the learning process is (or is best) technique based. Think about learning to cook. You start by following the recipe. Then you start to improvise. You understand that this ingredient is for flavor and can be adjusted to taste, but that ingredient provides aeration and messing with it too much will produce a dense, inedible result. Eventually you move beyond techniques and start to construct your own recipes from first principles. A poor education either starts with first principles, which a beginner does not have the experience to appreciate, or focuses too much on techniques divorced from context, which frustrates learners because they don't know how to properly apply techniques. I intended my book Clojure Polymorphism to position itself as a way to explore varied applications of the same tools and techniques, which I hope will guide readers from knowledge into wisdom.

The writing curriculum we use in homeschooling our children is technique based. A child reads an essay and creates an outline of the important points (there's a whole set of techniques for that). Then he will rewrite the essay from the outline applying techniques like "ly"-words, openers, and clinchers. This removes the hand wringing about what to write about. (Incidentally, if you read Ben Franklin's autobiography, this is the way he improved his own writing.) What if computer programming was taught this way? Here's a program that consumes a CSV file, changes some things, then writes it back out. First write out a high level algorithm for the program, then rewrite it using 3 of the 15 techniques you've learned (concurrency, multimethods, asynchronous channels, etc.). Repeat. I think this would produce wiser programmers.

However, eventually you need to move beyond techniques. Leaning on techniques is just shifting the problem elsewhere. Coining techniques is an attempt at mechanizing creativity, but instead of making creating mechanical, you are now faced with choosing which technique to apply to generate a creative solution. Now the creative leap must occur earlier in the process. You can try each technique in a brute force search, but I doubt many (if any) would consider that "creative," nor is it particularly efficient. The experience of repeatedly applying techniques should help you develop judgement and taste, so when you're faced with inventing from first principles, you have some gut sense or guiding aesthetic. That guiding aesthetic is not some set of rules for when to apply which techniques. If it were, then it would become a "library," so to speak. Anybody---or any machine--could evaluate the rules and perform the steps.

Techniques are great for broadening your learning, but they are not self applying. Learning all the techniques does not help you invent new techniques, nor will it induce creativity. You can know how to cut impeccable dovetails and square up lumber and drill straight holes, but that does not mean you will create beautiful furniture.

How does one develop this guiding aesthetic? You read a lot of other people's code. You write a lot of code. You read a lot of books. You work hard. Sorry, that's the best I've got. This is a continuing be continued.

However you do it, the end goal should be to move beyond techniques.