Vertex inputs and fragment outputs are all defined in programs by strings (the name of the input/output variables). But because vertex attribute bindings and FBO bindings are done by integers, not strings, there is this mapping that has to be put into programs to map from vertex inputs and fragment outputs to attribute buffer indexes.
This is, in a shader world, a waste of time. The problem is that attribute bindings and FBO bindings are numbers rather than strings.
I’m sure that this is one of those things that isn’t going to be changed because it isn’t a big enough deal for the ARB to actually fix, but it is highly annoying. It makes autogenerated attribute bindings in programs meaningless, since you can’t rely on the values. So you can’t autogenerate attribute bindings if you want to use the same VAO with different programs. Though less of a concern for FBOs, since you won’t be having that many of them, it causes the same problem.
The right solution is to bind FBO attachments and VAO attributes to strings rather than numbers. However, that’s probably too radical… for some reason. So failing that, why not get rid of the limitation on the attribute and buffer indices?
After all, the attribute index is just a number. So long as you don’t bind more than MAX_ATTRIBUTES of then in a single VAO or program, it doesn’t really matter that the indices you used are 50, 329, 65536, and 2^20. What matters is that the number stored in the program object and the number stored in the VAO match. This doesn’t require a single API change; it’s just a re-specification of what numbers you are allowed to use.
The FBO issue is a bit more complex, because of the way that glDrawBuffers is defined. So doing it there would require an API change; rather than taking an array of entries, it would have to take two arrays of equal length of entries. Or even better, just have a glLinkBuffer or something that takes a number and an FBO/default framebuffer enum, much like you make a call for each attribute in a VAO.
Remember: the point of this is to allow the user to be able to take a VAO of unknown origin, a shader of unknown origin, and render with them by strings alone. If they happen to be compatible (the VAO uses the same attribute names as the shader), then it works. Allowing any integer solves the problem by allowing the user to make a simple hash-function for the strings, and assign program attribute names based on that. And the same goes for FBOs.
I would prefer having new entripoints to just use strings directly, but I suspect the ARB wouldn’t be interested in that. Maybe this is more palatable.