The possibility that one might want multiple independent spaces of abstract ids is solvable by reduction. To introduce a new class of abstract ids, pick a new abstract id from the basic system to represent the new abstract id space, and implement abstract ids of this space as pairs of basic abstract ids, one being the space identifier, the other identifying the member of the space. Thus allocation of ids in separate spaces is easily implemented on top of the allocation of basic ids.
As for the assignment of object content to each allocated abstract id, the worst case is that an "empty" content must be distinguished as a way of coercing unattached ids to object ids, i.e. persons who wish they could have ids without assigned objects could for their own purposes interpret object indices with empty content as such. But we think it is actually quite natural to associate content proper with abstract ids. For example, when a new operator is introduced (as either defined or primitive) it seems most natural to associate with its identifier the formal object that gives its definition or that declares it primitive. In such cases, each occurrence of this new operator would directly refer to its definition (or declaration). When one introduces an abstract id for a procedure name, it would be quite natural to have that name refer to the object containing the source code that defines it. If one introduced an abstract id for a special purpose variable, it would be natural to associate an informal explanation of how that variable is intended to be used. In all these cases, it is good to associate with an abstract id some data explaining, either formally or informally, its use. Of course, the most common reason for introducing abstract ids will be in order simply to refer to objects in the first place.
IF YOU CAN SEE THIS go to http://www.cs.cornell.edu/Info/People/sfa/Nuprl/Shared/Xindentation_hack_doc.html