General Code Style Commandments

2015-01-17 | #styleguide

*Work in progress (still being expanded and linked to other guides)*


I: Thou shalt use Unicode/UTF-8 everywhere and always

There is no excuse for not doing this, be it for you source code, your exports, your databases, your outputs and even your documentation.

Every time you use any other encoding you better have a really good reason for doing so, because normally this is unacceptable. No, not even for performance, storage or legacy reasons.


II: Thou shalt use tabs for indentation

Yes, then your code will look different on every editor, that's the whole joke. If anything really needs to stay in place you can use blanks of course, but all general code indentation has to be tabs.

Besides the question of playing dictator over other peoples favourite code appearance: if you are writing code, which may be delivered as text/bytewise (HTML/JavaScript/CSS/XML/...), depending on you indentation settings, you blow up the file size unnecessarily 5 to 25%, which, in itself, is unexcusable.


III: Thou shalt use whitespace wisely

Whitespace is your friend. Writing seperationless code will not win you any awards or make your program 10% faster or 15% faster readable. Develop a schema and stick to it. Seperate parts of code semantically and structurally. Avoid glueing together blocks of code, let it breathe.

The details are yours to figure out, but I recommend going at it by code levels. My spacing pattern would be as follows:

3 blank lines between programm parts (classes/methods/end of member declarations/end of inclusions/...)

2 blank lines between logical blocks

1 blank line between algorithmic blocks / unbound comments / at the beginning and end of a container of other program parts

An example:

<?php

//###[ INCLUDES ]################################################################

require_once 'FooBar.absclass.php';

//###[ CLASS | BooFar ]##########################################################

/**

* Lorem ipsum dolor sit amet.

*

* @author Foo Bar

* @version 1.0

* @package foo

* @subpackage bar

*/

class BooFar extends FooBar {

// ### constants

/**

* Hey, a constant!

* @var String

*/

const HEYACONSTANT = 'foobar';

//###[ instance ]###########################################################

private $foo;

/**

* Constucts things.

*

* @param String $id identifies things

*/

public function __construct($id = ''){

parent::__construct($id);

$this->foo = '';

}

//###[ setter ]#############################################################

/**

* Sets foo. Is chainable.

*

* @param String $foo new value for foo

* @return BooFar method's instance

*/

public function setFoo($foo){

$this->foo = "$foo";

return $this;

}

//###[ getter ]#############################################################

/**

* Returns current value of foo.

*

* @return null

*/

public function getFoo(){

return $this->foo;

}

//###[ output ]#############################################################

/**

* Do very elaborate stuff with foo and print result to StdOut.

*/

public function render(){

$result = '';

$answerToEverything = 42;

$illuminatiNumber = 23;

$numbers = array(1, 2, 3, 4, 5, 6, 7, 8, 9);

$tmpResult = 0;

for( $numbers as $number ){

$tmpResult = $number % $answerToEverything * $illuminatiNumber;

if( $tmpResult > 1 ){

$result .= "$tmpResult";

}

}

echo self::HEYACONSTANT.' '.$result;

}

}

?>


IV: Thou shalt name things by purpose

This is so common it sometimes hurts. Don't, for the love of god, name things according to what they _are_, but according to what their _purpose_ is.

Bad:

var fiftyMinusEight = 42;

$veryBrightRed: #ff0000;

$text2 = 'Lorem ipsum dolor sit amet.';

public Button actionTrigger;

<div class="container">Lorem ipsum</div>

Good:

var theAnswerToLifeTheUniverseAndEverythingElse = 42;

$brandColorHighlight: #ff0000;

$contentDummyCopyText = 'Lorem ipsum dolor sit amet.';

public Button articleEditFormSubmitButton;

<div class="container dummytext copy">Lorem ipsum</div>

There are some very limited exceptions to this rule I find acceptable: Iterations and recursions often use standard temp variables and accumulators, which are so common that those can be accepted as being purposefully named. i, j and k are iteration names. index, key and value are viable foreach-holders. tmp and temp are viable names for technically necessary variables to hold half-completed values.


V: Thou shalt not repeat thyself

If you use copy & paste you are most likely doing something lazy and suboptimal. Every definition should be kept in a singular place and should be reused. There are very few exceptions to this rule, most of them technical, none of them are a coding style

Everything you type or include more then once for the same or a similar context is likely to be redundant and should be refactored to be in one place instead. Generalization first then specialize from there.


VI: Thou shalt not reinvent the wheel

We are all the best programmers ever born. That's why our solution to a certain problem is definitely better than the default implementation. But guess what: we don't care.

If there is a standard solution for something, then do use it. If there exists an accepted standard for something, stick to it.

You may leave tread-out paths whenever you like though, provided you got a good reason for it. And even if you do so: stick to common conventions, making it possible for any other person then yourself to understand by reading, what the hell you were doing.


VII: Thou shalt case everything systematically and according to standards

Programming knows o so many casings. I know, it's difficult to get them right all the time, but keep in mind: they are important, because they immediately convey what type of data you are handling, so always, I repeat, ALWAYS case your stuff correctly.

Classes use CamelCasing with a leading captial letter.

Class-members and methods as well as functions generally use camelCasing.

Constants and invariables use CAPTIAL_UNDERSCORE_CASING.

File paths are written only in small-letters-with-dashes.

Template-variables (in the templates) are written in small_letters_with_underscores.

Many languages and dialects have own variation to these rules. Use them, instead of sticking to the definitions above. Python for example uses snake_casing for members and methods and we all expect you to know and use this and in HTML/CSS you'll be crucified for using anything but small letters and dashes in identifiers. Learn that stuff and apply what you've learned.


VIII: Thou shalt not use magic numbers

case 1, 23, 42, 66:

if( response.code == 123 )

Those are lines which wanna make you pull your hair out. Arbitrary numbers used in a hundred places, some identical for different purposes. There is nearly no excuse for this, but laziness. If there are indeed numbers, which hold a specific meaning, then be a nice programmer and create a constant with a human-readable name for it.

const THE_ANSWER_TO_EVERYTHING = 42;

define('ERROR_CODE_FILE_CORRUPT', 7);

are alright.

The only exception I can think of, which _may_ be okay to do, is using magic numbers every developer just has to know.

if( httpresponse.code == 200 ){

for example seems alright to me. But even that would be cleaner by saying

if( httpresponse.code = HTTP_CODE_OK ){


IX: Thou shalt provide information on how to get your stuff running with your code

Often you'll get some package with a comment like: "Hey I wrote this plugin, maybe you can use it in you project". I could, if I would know how or had the nerve of deconstructing your mind sphere. I'm not such a fanatic defender of extensive documentation, but a few concise words about how to set up a project, what preconditions have to be fulfilled and into what traps I might step would be great.

Just put in a nicely written readme and provide requirement files for all required external packages. Thanks a lot.


IX: Thou shalt write useful commentary

Comments in itself offer no value. That's heresy, I know, but stay with me. More often then not you'll see comments like this:

/**

* Adds X to Y

*/

function addXtoY(x, y){

return x + y;

}

No shit, Sherlock! That's just wasted space.

Another offender:

// create new object and apply config

$obj = new Object(conf);

You don't say! Well, thank you so much! In such projects you can count on the fact, that there are hundreds upon hundreds of lines of filler commentary, but above those lines that would really count, there's nothing to explain whats going on. A recent discovery of mine:

// need empty fake routes

window.foundationRoutes = [];

Good to know, but why? And what for? I can see that this is obviously an intially empty array of routes. The real question is "Whyyyyyy?". After some digging around:

// need empty fake routes

// for 'foundation.dynamicRouting'

// see https://github.com/zurb/foundation-apps/issues/583

window.foundationRoutes = [];

So please, don't annoy us with comments repeating exactly what the source says anyway, but provide helpful context for it.

Other types of comments I really like to see:

1. Structuring comments, splitting parts of a class or module (as seen above in the example of III)

2. Machine readable heads and signatures of public functions, so that the code completion tells me everything I need to know, when using the function somewhere else.

3. A sentence to introduce the purpose of a module or class to me

Always provided you apply all other common rules like purposefully naming things and keeping a clear structure: the rest of the comments may go to hell!