Here is what the documentation for attribute::add (which lives in acs-subsite) says:
wrapper for the acs_attribute.create_attribute call. Note that this procedure assumes type-specific storage.
It adds a column to the type specific table whereas
dotlrn_community::set_attribute is setting an attribute
for a specific object_id (and I think uses a generic table).
Whether you use a generic table or a type specific table
is sort of an implementation issue and the right decision
depends a little on how sparse the attribute values are,
how many rows there are in the type specific table and
so on. neither is really right or wrong.
also both functions are in the wrong place. acs-subsite and
dotlrn both have a lot of generic code that belongs
elsewhere.