code guide

zen

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

from python-zen

complexity

Many (open source) hackers are proud if they achieve large amounts of code, because they believe the more lines of code they've written, the more progress they have made. The more progress they have made, the more skilled they are. This is simply a delusion.

Most hackers actually don't care much about code quality. Thus, if they get something working which seems to solve a problem, they stick with it. If this kind of software development is applied to the same source code throughout its entire life-cycle, we're left with large amounts of code, a totally screwed code structure, and a flawed system design. This is because of a lack of conceptual clarity and integrity in the development process.

Code complexity is the mother of bloated, hard to use, and totally inconsistent software. With complex code, problems are solved in suboptimal ways, valuable resources are endlessly tied up, performance slows to a halt, and vulnerabilities become a commonplace. The only solution is to scrap the entire project and rewrite it from scratch.

The bad news: quality rewrites rarely happen, because hackers are proud of large amounts of code. They think they understand the complexity in the code, thus there's no need to rewrite it. They think of themselves as masterminds, understanding what others can never hope to grasp. To these types, complex software is the ideal.

Ingenious ideas are simple. Ingenious software is simple. Simplicity is the heart of the Unix philosophy. The more code lines you have removed, the more progress you have made. As the number of lines of code in your software shrinks, the more skilled you have become and the less your software sucks.

from suckless-philosophy

name

Finally, I prefer minimum-length but maximum-information names, and then let the context fill in the rest. Globals, for instance, typically have little context when they are used, so their names need to be relatively evocative. Thus I say maxphysaddr (not MaximumPhysicalAddress) for a global variable, but np not NodePointer for a pointer locally defined and used. This is largely a matter of taste, but taste is relevant to clarity.

from pike-style

optimize

from pike-rules

handle

Don't use the nouns "Object", "Manager", "Handler", or "Data" in class names. These words say nothing about the responsibility of the class, leading maintenance programmers to lump all kinds of irrelevant crap into the class. Think instead about what the class is actually supposed to do and name it after that.

from dont-name-classes

globals

Global Variables Should Be Avoided When Unnecessary

from global-bad

  1. When in doubt, parameterize
  2. Bundle globals into structs/records/classes.
  3. Favor pure functions
  4. Encapsulate (loosely) at the level of namespaces/packages/modules.
  5. Don't be afraid of long functions.

from oop-bad t=34m58s

structure

What people tend to create when they design object oriented programs are overly architected buildings, where the walls have been prematurely erected before we have really figured out what the needs of the floor plan are. And so what happens is down the line, turns out: "Oh wait! We need to get from this room over here to that room over there, but, oh wait! We have erected barriers in between." So we end up busting a bunch of holes through all the walls, like the Kool-Aid guy, and the resulting pattern is really not organized at all, it's just swiss cheese. We thought we were being disciplined, neatly modularizing all the state, but then the requirements changed, or we just didn't anticipate certain details of the implementation and we end up with a mess.

The lesson we should take from this is to be very careful about erecting barriers, about imposing structure. It's actually better to start out with a free-form absence of structure, rather then impose a structure that will likely turn out to not really fit our problem. Bad structure that doesn't really fit our problem not only makes it harder to implement the code in the first place, it hinders change, and it confuses anyone who looks at our code because it's implying one thing, but then what's really going on is another.

In the Object-oriented world, we have to think about all these graphs. We have to think about an inheritance hierarchy, we have to think about a composition graph, we have to think about data flows between the objects and also we're thinking about a call graph.

The liberating thing about procedural code is that there's just the call graph.

We also, of course, do have to think about how our data is structured, and how our data gets transformed throughout the course of the program, but the beauty of procedural code is that we can think about them totally independent of any notion of responsibilities. When looking at my data I can think just about my data. And when looking at my functions, I'm not thinking about all these self imposed barriers.

from oop-bad t=25m40s

long functions

// Long functions are good.

// Sequential code is easy to read.

// Write code that does something.

// Alert names: manager, controller, handler

I think that long functions are good, which is controversial. Some computer science people teach that you should never have a function with more than five lines of code.

Sequential code is really easy to read. That's how we read books: From the top to the bottom. Reading a "Choose your own adventure"-book where you have to flip to page 57 to finish a sentence is much harder.

I like writing code that does something. People tend to write a lot of functions or things that handle other code. If a lot of your code is called like SomethingManager or SomethingController or SomethingHandler, you're probably not writing code that does something, you're writing code that handles other pieces of code. That's a warning flag. It's really hard for someone from the outside to know what that "handler" actually does, whereas if it's a functions that's assigned as "this functions does this thing", then it's much clearer what's going on.

paraphrased from how-i-c

guard clause

Here is a sample of code using guard clauses ...

public Foo merge (Foo a, Foo b) {
	if (a == null) return b;
	if (b == null) return a;
	// complicated merge code goes here.
}

Some style guides would have us write this with a single return as follows ...

public Foo merge (Foo a, Foo b) {
	Foo result;
	if (a != null) {
		if (b != null) {
			// complicated merge code goes here.
		} else {
			result = a;
		}
	} else {
		result = b;
	}
	return result;
}

from guard-clause

worse is better

from worse-is-better

indentation

Use tabs for indentation and spaces for alignment.

from suckless-style

Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3.

Rationale: The whole idea behind indentation is to clearly define where a block of control starts and ends. Especially when you've been looking at your screen for 20 straight hours, you'll find it a lot easier to see how the indentation works if you have large indentations.

Now, some people will claim that having 8-character indentations makes the code move too far to the right, and makes it hard to read on a 80-character terminal screen. The answer to that is that if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program.

In short, 8-char indents make things easier to read, and have the added benefit of warning you when you're nesting your functions too deep. Heed that warning.

from kernel-style

columns

Keep lines to reasonable length (max 79 characters).

from suckless-style

quality

Next time management or clients try to convince you to move faster and throw quality under the bus, you can say sure, that will work, as long as you can hire 429 engineers to work on our iOS app.

from facebook-quality

related