Synchronization of history, not state
An object's state is dependent upon its history.
When an object is constructed, it is initialized to a starting state. From then on, every action performed on that object changes its state. If you constructed another object and performed exactly the same actions on it, then it would end up in exactly the same state.
Suppose the object is a chess board. Its initial state has the two teams facing off against each other. Each move alters that state by one or two pieces. Start a new game and make the same moves, and the board will end up in the same position.
Caching aside, it is better to store independent data than dependent data. The dependent data can be calculated from the independent data, so there is no loss of information.
But the converse is not true. Several different sequences of moves could lead to the same board position. Given a board position, it is impossible to determine exactly which path was taken to get there.
The current state of an object is usually sufficient to make business decisions. That's why most of our business systems can get by with storing state, not history. A chess player makes his next move based solely on the current position of the pieces.
But the current state of an object does not carry sufficient information for synchronization. Synchronization is all about bringing two or more discrete representations into agreement. If I claim that an object is in one state, and you claim that it is in another, who is right? To decide, we have to go back through the histories and see where they diverge.
In an imperative object-oriented language, every mutating operation performed on an object causes changes to its member variables. Code inside the body of the method assigns new values to the members of the object. The prior state of the object, combined with the parameters of the method, determine what values get assigned.
If we allow our languages to be more functional and declarative, we could instead express the current state as a function of history. Suppose that there was no code in the method. The object just records the fact that the method was called. Now, move the code to the member variable. Its job is to calculate the value of that member variable given the history of method calls.
With this new declaration of an object, the current state is calculated based on history. From the outside it looks the same. You can call a method, then observe the state of the object to see that it has changed. The difference is that the method call did not imperatively change the state of the object, it just recorded a fact. It was the observation of that object's state, seeing this new fact, that caused the change. And now that the object retains history, it can be easily synchronized.
My synchronization system uses history, not state, to persist, exchange, and represent objects.