GLSL : recommendations
Here are a few quick recommendations for your GLSL code.
No matter what your target GL version is, it is best to put the version number at the top of each shader (vertex shader, geometry shader, fragment shader and any other shader stage). It would look like this
where the above version number means 1.10 in this particular example.
It makes things clearer. People will understand what version of GLSL you are aiming for and so they don't have to guess it by looking at the rest of the code. Also, the driver might be more strict in terms of the syntax if it sees that. Strictness is a good thing because it enforces the GLSL standard and no additional features that the IHV might provide (IHV such as nVidia).
It is nice to put some comments in your code.
This one is obvious : write //VERTEX SHADER at the top of your vertex shader. Write //FRAGMENT SHADER at the top of your fragment shader
No Missing Shader
For GL 2.0 and 2.1, it was possible to just have a vertex shader and no fragment shader. In this case, the fixed pipeline would take care of the fragment processing. You could also have a fragment shader with no vertex shader. It is good practice to get into the habit of thinking of the GPU as a programmable device.
In GL 3.0 forward compatible context, everything is done with shaders.
For GL 2.0 and 2.1, you could make use of built in uniforms such as gl_ProjectionMatrix and gl_ModelViewProjectionMatrix and many others.
It is strongly recommended that you get rid of these and use your own uniforms.
In GL 3.0 forward compatible context, you are forced to make up your own uniforms.
Vertex or Fragment Stage?
You might be tempted to write some part of your code in the fragment stage. Is it possible to move that piece of code to the vertex stage and send the result to the fragment stage as a varying?
Try to not overburden the fragment processors of your GPU.
This page discusses some optimization concepts
The All In One Shader
There is a temptation to just have 1 shader that does all : 100 lights and textures and bump mapping that can be turned on and off at the flip of a boolean uniform. Boolean uniforms and for loops all over the place.
Consider writing separate shaders for different cases. Consider writing a tool that auto-generates some of your shaders.