As Asgard already pointed out, it is permissible to include any single vertex attribute or result binding in executable program instructions. Think of it as an automatic variable declaration. It is also allowable to include program parameter (constant) bindings, except for multiple-element arrays (single elements of matrices are OK). So, the classic 4x4 matrix transform can be written something like:
DP4 result.position.x, vertex.position, state.matrix.mvp[0];
DP4 result.position.y, vertex.position, state.matrix.mvp[1];
DP4 result.position.z, vertex.position, state.matrix.mvp[2];
DP4 result.position.w, vertex.position, state.matrix.mvp[3];
In this example, you might want to declare variables so the instructions aren’t so long. But we put this functionality in so you didn’t have to worry about declaring every single little binding you use in the program. There’s no ambiguity when you say “vertex.position” in a program, so there is little benefit to requiring variable declarations.
The only variables that need to be declared are temporaries and address register variables, since these have no “bindings”.
As for attribute aliasing, use whatever fits into your application the best.
If you are using vertex programs pretty much exclusively, generic attributes are probably the way to go.
If you are giving the same geometry to both vertex programs and the fixed-function pipe, you should probably use conventional attributes as much as possible – a vertex program can still refer to the conventional color as “vertex.color”.
If conventional attributes make sense, but you have a couple attributes that you use only for vertex programs, put them in attribute slots that don’t alias with the attributes you use. In general, attributes 6 and 7 are always free. Plus, if you use only 4 texture coordinates, slots 12-15 are free.
Conventional and generic vertex attribute arrays play together – you can enable both and get both to your program. For example, if you used conventional vertex position and generic attribute 7, you could render with vertex arrays using:
glVertexPointer(…);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointerARB(7,…);
glEnableVertexAttribArrayARB(7);
glDrawArrays(…); // or whatever
The array state itself does not alias – setting the color pointer doesn’t ever set the pointer for vertex attribute 3. However, if the color and attribute 3 arrays are both enabled, aliasing behavior still applies and the generic attribute “wins” in the sense that it is defined. Think of array rendering in this case as though you called:
glColor(…);
glVertexAttribARB(3,…);
The second call leaves the current color undefined due to aliasing.
Be careful not to rely on the aliasing behavior – setting attribute 3 will also set “vertex.color” on NVIDIA platforms, but not on ATI platforms, for example.
The spec helps you avoid this a little bit by disallowing programs that refer both to “vertex.color” and “vertex.attrib[3]”.
But there is no mechanism to prevent you from using glVertexAttrib(3,…) when your program (or fixed-function GL) wants to use glColor(), or vice versa.