loading...

State-of-the-Art Shitcode Principles

trekhleb profile image Oleksii Trekhleb ・2 min read

This a list of state-of-the-art shitcode principles your project should follow.

💩 Full version of the list on GitHub

Alt Text

Get Your Badge

If your repository follows the state-of-the-art shitcode principles you may use the following "state-of-the-art shitcode" badge:

State-of-the-art Shitcode

[![State-of-the-art Shitcode](https://img.shields.io/static/v1?label=State-of-the-art&message=Shitcode&color=7B5804)](https://github.com/trekhleb/state-of-the-art-shitcode)

The Principles

💩 Name variables in a way as if your code was already obfuscated

Less keystrokes, more time for you.

Good 👍🏻

let a = 42;

Bad 👎🏻

let age = 42;

💩 Mix variable/functions naming style

Celebrate the difference.

Good 👍🏻

let wWidth = 640;
let w_height = 480;

Bad 👎🏻

let windowWidth = 640;
let windowHeight = 480;

💩 Never write comments

No one is going to read your code anyway.

Good 👍🏻

const cdr = 700;

Bad 👎🏻

// Callback function debounce rate in milliseconds.
const callbackDebounceRate = 700;

💩 Always write comments in your native language

If you violated the "No comments" principle then at least try to write comments in a language that is different from the language you use to write the code. If your native language is English you may violate this principle.

Good 👍🏻

// Закриваємо модальне віконечко при виникненні помилки.
toggleModal(false);

Bad 👎🏻

// Hide modal window on error.
toggleModal(false);

💩 Try to mix formatting style as much as possible

Celebrate the difference.

Good 👍🏻

let i = ['tomato', 'onion', 'mushrooms'];
let d = [ "ketchup", "mayonnaise" ];

Bad 👎🏻

let ingredients = ['tomato', 'onion', 'mushrooms'];
let dressings = ['ketchup', 'mayonnaise'];

💩 Put as much code as possible into one line

Good 👍🏻

document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];return o},{})

Bad 👎🏻

document.location.search
  .replace(/(^\?)/, '')
  .split('&')
  .reduce((searchParams, keyValuePair) => {
    keyValuePair = keyValuePair.split('=');
    searchParams[keyValuePair[0]] = keyValuePair[1];
    return searchParams;
  },
  {}
)

💩 Fail silently

Whenever you catch an error it is not necessary for anyone to know about it. No logs, no error modals, chill.

Good 👍🏻

try {
  // Something unpredictable.
} catch (error) {
  // tss... 🤫
}

Bad 👎🏻

try {
  // Something unpredictable.
} catch (error) {
  setErrorMessage(error.message);
  // and/or
  logError(error);
}

💩 Do not lock your dependencies

Update your dependencies on each new installation in uncontrolled way. Why stick to the past, let's use the cutting edge libraries versions.

Good 👍🏻

$ ls -la

package.json

Bad 👎🏻

$ ls -la

package.json
package-lock.json

💩 Triangle principle

Be like a bird - nest, nest, nest.

Good 👍🏻

function someFunction() {
  if (condition1) {
    if (condition2) {
      asyncFunction(params, (result) => {
        if (result) {
          for (;;) {
            if (condition3) {
            }
          }
        }
      })
    }
  }
}

Bad 👎🏻

function someFunction() {
  if (!condition1 || !condition2) {
    return;
  }

  const result = await asyncFunction(params);
  if (!result) {
    return;
  }

  for (;;) {
    if (condition3) {
    }
  }
}

💩 Avoid covering your code with tests

This is a duplicate and unnecessary amount of work.

Discussion

pic
Editor guide
Collapse
sergchr profile image
Sergiy

Thanks, Oleksii, for the great coverage of how a developer should write good code!
From my perspective, I would add the following:

Variables naming

The shorter, the better:

const s = 1000

instead of

const MILLISECONDS_IN_ONE_SECOND = 1000

You should decrease your variables/functions names.

Comments

Write comments in your native language - totally agree!
In case you need to leave a comment about fixing something in the future, please use it like this:

// TODO: fix
// or
// fix
// or
// sửa tôi
function add (a, b) { return a - b }

Not like this:

// FIXME: this function returns an invalid result
// the problem could be in the incorrect algorithm chosen
// to calculate a result
function add (a, b) { return a - b }

One-line code

You should write a one-line code because it can save a ton of memory! Just imagine how much performance gain you reach once you rewrite your app into one-liners!

Errors

Just don't catch them, I agree with Oleksii. You will see errors if your app fails anyway, so why do you need to write additional code to catch them?

Callbacks vs. straightforward code

Use callbacks. Especially, if you have more than 5 of them.

Bonuses:

this manipulating

Don't create too many variables, just use "this" context!
Examples:

this.f = () => {
 return err("error")
}

// as you remember: use shorter names, this is bad name
const err = u => throw new Error(u)

// 1. Also bad function name
// 2. Good names for arguments
// 3. Function takes more than 2-3 arguments which is great
function calculateHash(context, cb, k, e, i, few) {
  if (this.true == context.true) return cb(false)
  if (typeof this.cb === 'function') k(cb(i))
  return md5(k(i), few + e)
}

Functions return signature

Write functions that can return multiple types and unexpected results like this:

function getFirstName(user) {
 if (typeof user === 'object') return user.firstName
 if (typeof user === 'number') return user
 if (typeof user === 'string') return { firstName: user }
 if (user.firstName && user.isReal) return function () { return user }
 if (this.user) {
   return NaN
 } else {
   return this.user + { user }
 }
}

Code linting

Just don't use tools for code linting. They only take additional place in your "package.json".
Write code as you want, especially if there is more than one developer in a team.

Unnecessary code

Don't delete the code your app doesn't use. At most, comment it.

Logic fragmentation

Don't divide a program logic into readable pieces. What if your IDE's search brokes and you will not be able to find the necessary file or function?

  • 10 000 lines of code in one file is pretty OK.
  • 1000 lines of a function body is pretty OK.
  • Dealing with many services (3rd party and internal, also, there are some helpers, database hand-written ORM and jQuery slider) in one service.js? It's OK.
Collapse
trekhleb profile image
Oleksii Trekhleb Author

Very good points! I've updated the main list 👍🏻

Collapse
ghost profile image
Ghost

Fun post but

💩 Never write comments

const cdr = 700;
// Callback function debounce rate in milliseconds.
const callbackDebounceRate = 700;

I would say that changing the variable name was enough, I think that the comment is redundant :D, if the fact that is in ms is not obvious I would put it in the variable name. For the example I would put something in the lines of

// In milliseconds because some reason or 700 calculate empirically, some 'why'
// not some 'what'. If the 'what' is not clear in the code, the code is probably
// too messy.
Collapse
trekhleb profile image
Oleksii Trekhleb Author

This is a very good point about the comments. I've updated the main list. Thanks!

Collapse
theodesp profile image
Theofanis Despoudis

I think we need an eslint plugin for that also!