How to write a chess evaluation function? I don't know very much about chess beyond the rules but I enjoy programming and am trying to write a chess engine. I recently found this evaluation function: Simple Evaluation Function. What would be the best way to improve on what has been done there?
EDIT for comment

The most important by far is the material count and PST already discussed in your link. You won't go anywhere unless your engine can count materials properly. Other than that, the common knowledge such as rook behind a passed pawn, castled king, pawn majority and mobility are important. Your human knowledge to chess should be sufficient.

ORIGINAL

The best way to improve it is to study the Stockfish source code. Read the comments, and study the implementation.

Code your engine, make it work with a simple evaluation function. Gradually and slowly apply Stockfish's ideas to your own engine.

There's many possible improvements. I can only list some of those. I will give you a link to the Stockfish source code below.


Two bishops advantage
Interpolate between middle game and endgame scoring
Bonus to pawn structures (the page only gives very simple PST values) 
Calibrate the values better with a statistical model
Castled king
Number of squares controlled
Number of attacking squares near the enemy's king
Asymmetric evaluation (Stockfish doesn't do that but some engines like Chess Genius does that)
Pieces attacked by the king
Rook behind a pawn
Pawn on the check colour as bishop
Mobility bonus
Enemy checks
Rook on semi- or open file
Insufficient defended squares
Passed pawn that is not blocked
Candidate passed pawn (pawn majority)
......


Let's take some random examples from Stockfish. Please examine the source code yourself for details.


  https://github.com/official-stockfish/Stockfish/blob/69eb391cd779223c331fb0de80392cbd323055a9/src/evaluate.cpp


// RookOnFile[semiopen/open] contains bonuses for each rook when there is no
// friendly pawn on the rook file.
const Score RookOnFile[] = { S(20, 7), S(45, 20) };


and

// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
// which piece type attacks which one. Attacks on lesser pieces which are
// pawn-defended are not considered.
const Score ThreatByMinor[PIECE_TYPE_NB] = {
  S(0, 0), S(0, 33), S(45, 43), S(46, 47), S(72, 107), S(48, 118)
};


and

// Scale down bonus for candidate passers which need more than one
// pawn push to become passed or have a pawn in front of them.
if (!pos.pawn_passed(Us, s + pawn_push(Us)) || (pos.pieces(PAWN) &amp; forward_bb(Us, s)))
        mbonus /= 2, ebonus /= 2;