On the semantics and implementation of replicated data types