What makes how people think different from how computers think is our use of concepts. Reading the news doesn’t simply tell me that tell me that a drinking wine might not be as good to our health as we previously thought (Red Wine is bad for you Say Experts). Because I think with concepts I can check the validity of the claim (research paper says that when controlled for wealth, the health benefits of wine disappear), I know that this information might affect my brother who enjoys a casual drink, and I also know that I should probably tell him to drink less. In other words, concepts aren’t just simply models or processes. They help us decide what information is relevant, what other information we might need to find, and how we should respond. There is a lot of functionality that our concept system helps us do.
The reason I bring this up is because without understanding concepts and what they do, we are blind to the fact that code and it’s documentation is broken. What I mean is that code and documentation is a puzzle left for the user to figure out. Like someone who has lost a limb and learns to live a normal yet inconvenient life, we’ve learnt to adapt and live with it. Let me try and explain.
At a high level, concepts exist to do one thing: help you solve problems. Concepts do this by:
- Letting you know what information is important
- Telling you when to use it
- Helping you evaluate or predict situations
- Suggesting courses of action
- Making decisions
Imagine that you like a new open source project and you decide to contribute to it. What do you do? You go through the file system, read lines of code, and if you’re lucky you find some documentation that points you in the right direction. But at the end of the day, it’s up to the reader to walk through folder-by-folder, file-by-file and understand how the thing works. Nowhere are we ever really told how things work. Documentation suffers from this same problem. A person can’t learn to understand a framework or an API unless they understand more conceptual aspects of the code base. If you go to Apple’s developer API reference page and try to learn how to code apps that way, you’d be lost. Documentation, as it is, only provides a certain type of information: mostly class descriptions, functions, syntax, and examples. There is little to no information that links it all together. There’s no conceptual work being done.
No conceptual information = lost and confused programmer.
Here’s an example of someone who did the conceptual work. Flexbox. If you don’t read it here’s one comment.
Thanks for this — suddenly all the other flexbox tutorials make sense. Though I’m totally comfortable with HTML and CSS (even the intricacies and quirks of CSS positioning) something about flexbox has always felt elusive. Your tutorial took that thing that just hadn’t “clicked” for me (whatever it was) and made it “click.”
How are concepts built?
Information generally needs to do two things in order to be built up into a working concept. The first thing is you need is a high-level understanding of what the concept is used for. For example, before you can properly use a function, you need to know what it can do in a greater context. NSLayoutConstraint is a function apart of Apple’s UIKit API (Apple’s iOS UI Library). The function is used in order to define the relationships of objects to the screen and other objects. It helps make apps fit on different sized screens without looking strange. This type of information about what the function does ties the information to problems and goals. Now I know that when I want to make sure my app scales to different size screens, I should put use NSLayoutConstraint (Tells you when to use it, also suggests a course of action). It also helps me know what I should think about when problems to do with scaling arise. This is purpose knowledge.
The second type of information is mechanical knowledge. Documentation mainly succeeds at providing this type of knowledge. Mechanical knowledge is about learning all the rules and behaviors of things that let you use the concept. With only what I explained above about NSLayoutConstraint you could only know what the function did and when to use it. You’d have no idea how to use it. Mechanical knowledge is about learning how to follow the right thinking procedure. You need to know the inputs and outputs, the syntax and how it behaves. Much of this knowledge is organized through models. To use NSLayoutConstraint you have to understand trailing, spacing, priorities, and other attributes. All of these things help you predict what code will compile into, and how to actually do what we learn.
In order to go from a problem to solution, you need both the high-level purpose information and the low-level mechanics information. A concept that has both purpose and mechanics information is Problem Solving Complete or PS Complete for short. Although well-written code and documentation makes deciphering code much easier, there is a lot of room for improvement.
This isn’t to say that coming up with a good way to organize and communicate concepts is easy. The model I just gave only lets you understand the type of work that needs to be done; it doesn’t tell us what we can nor should do.
But before we head into describing how we might change the way we organize our code and documentation we should talk about a few of the Goals that code and documentation should have.
- Easy to learn and understand
This goal sums up my main criticism of the organization of code and documentation. We want the code and documentation that we write to be easier to learn and understand. This goes beyond just adding in comments and RMEs. We want people from code maintainers, to new users to be able to go in and easily learn how everything works.
In order to do this we will need:
Purpose Information (Architectural Design and Problem Description)
This is the high-level information that describes where code is and what it does. The reasons and benefits are described earlier.
To be Searchable and Discoverable
There is one fatal flaw in keeping the organization of documentation the way that it is (a list of classes or functions). People can’t find the function that they want (or they might not even know that it even exists). In general, the solution to finding out how to do something is a google search of your problem. If no-one has asked the question before you can ask Stack Overflow. And if none of that works, as is with new and niche code bases, then you’re on your own.
The big benefit to presenting conceptually presenting documentation is that people can search for functionality that they need more easily.
- Helps the Design and writing of Code.
One of the benefits of having a conceptually solid design for code is that coding it becomes a lot easier. Although lots of code is hacked together, it should at some point be conceptualized. Decisions about how someone should think about an object, or how something behaves needs to be set out clearly. Architectural changes done later on have large costs and waste a lot of time.
Think about some of the best APIs you’ve used. Most are very simple. Or at least conceptually simple. Everything about them feels intuitive and the code reads very simply.
- Secondary Goals
Obviously we want to save as much time and energy of our coding to making meaningful changes. Time spent trying to understand or learn something is a deadweight loss.
Now that we have a pretty good idea about how code should work, we can move onto how we can go about organizing our code and documentation to help us do that.
This is part 1 in an ongoing series on concepts in the design and writing of code and documentation.
In part 2. I will describe different tools we can use to achieve our goals.
P.S. Please leave feedback both on the content and the writing itself! I’d also love to answer any questions you might have. This has been a long time coming and means a lot. Thanks in advance!