OK. I think I see here the reason for the confusion. I believe it comes down to a difference in basic assumptions.
It all boils down to what the definition of an object is, and to what you think you are passing in the data flow.
The way I see it, what most end users would think of as an object are what Richard Hickey would refer to as an Entity.
Something that has both identity and state, and can be modified.
If you are interested in Richard Hickey`s comments about entities (and other things) he has
a video and there is also
a transcrpt available if you prefer to read it.
With Richard Hickey`s approach, the data you pass between calls are not entities, but entity snapshots instead.
Entity snapshots represent an entity at a specific point in time. As such, snapshots are immutable.
So when you "modify" a snapshot, you create a new snapshot - not of the entity at a point in time, but of the entity at a possible new point in time.
To actually change the entity, you need to somehow update the entity with the state from a snapshot.
So my "IPs" aren`t entities - they are just snapshots, value aggregates or simple values.
They are all just (immutable) values. That is why I don`t call them IPs - they do not fit the definition.
If you duplicate a snapsnot - and "modify" one of the duplicates (actually replace it with a different snapshot)
Then they represent two different potential future (what if) versions of the entity.
It is up to you to decide which one becomes real, or possibly both could be real, just at different points in time.
There is never any possibility of conflict between different snapshots, even if they are of the same entity.
In the JavaFBP approach. The object being passed (the IP) can be an entity (although I would suspect that generally it is not).
The rule that applies is that the IP is supposed to be owned only by the process of the component that it is being processed in,
and such ownership transfers as it flows between components.
I thought originally that this rule was intended to preserve the visibility of the IP to changes
(so that it couldn`t be changed by two components at the same time)
But now I believe it was intended to preserve the integrity of the current state of the entity being passed
(in other words - to prevent multiple versions).
I`m not sure you remember, but in one of the FBP meetups, I asked if the IP being passed was attached to something outside the flow.
And you answered with the above rule.
For me. An entity exists in a particular location. I has an identifier, and lives in a container of some sort (a database, a memory cache, the system itself)
You can`t take the entity out of its container without changing its discoverability, and as far as the rest of the system is concerned,
that effectively destroys the entity (its identity) and replaces it with another..
So for me. If an object is owned purely by the flow process - then it can`t possibly be a usable entity - because it is not discoverable via its identifier and container.
And if that is the case, whether the object is immutable or not, then the object must be just a snapshot.
In which case, you don`t need to worry about entity current-state integrity - because it is not an entity - just a snapshot - it is OK to have multiple versions and copies.
I guess that I`ve internalized this approach so strongly that I think I have finally completed my transition out of object-think.
It`s a victory of sorts... but it makes communication difficult with (the vast majority of) other programmers who haven`t yet made the transition.
I suppose an entity could be transmitted through a flow and changed within the flow
as long as you first removed it from the original container and placed it back at the end.
The downside is that the entity would temporarily be unavailable for any other purpose while it was in transition,
but I suppose it could be acceptable if no activity was expected against it.
With the kind of applications I tend to work with (mostly distributed and web-based)
it is unacceptable to make an entity unavailable for any period of time, so I tend to push that view of things.
In fact, given my focus on distributed programming, I have a hard time even understanding where it could be considered acceptable...
I tend to think of it as an error - or at least something that is potentiallty dangerous.