Trying to grasp the concept of Immutability for my debut Redux (NGRX/Store) endeavor has been quite the challenge. Avoiding state mutation has been a struggle, especially while dealing with Object.assign({}) and state mutation errors. Thankfully, I stumbled upon Immutable.JS, which has made my life much easier.
Imagine having a Financial Trading Application that needs to showcase a collection of Bars on a chart upon loading. The last bar must be updated periodically with live price data, and new bars are added intermittently.
All of this must be executed for {1-n} financial instruments (EURUSD/GBPJPY/Gold/Oil etc.). To tackle this aspect of my application, I have come up with the following model:
export interface CandleState {
LastCompletedCandle : Candle;
InProgressCandle : Candle;
LastTick:Offer;
ClosedCandles:immutable.List<Candle>;
};
export interface AllCandleState {
instruments: immutable.Map<string, CandleState>
}
It is worth noting that I am utilizing an Immutable Map that contains an Immutable List. My initial question is: Is there a purpose to having 'immutability within immutability' in this scenario? When I call
instruments.set("EURUSD", { [my new state] })
I am essentially receiving an entirely new state, so I am uncertain if nested immutability is necessary. I want to be able to subscribe to changes on the ClosedCandles list; will making it immutable enable direct observation of these changes? Or are changes only detected at the 'top' level?
Another question that arises is: should I be concerned about this at all? I have a notion that altering an immutable collection is a costly operation. If I use list.push or map.set, what exactly occurs behind the scenes? Am I copying every item in the array or map into a new array/map every time a modification is made to an immutable collection? Or is it merely a change in reference?
It would be helpful to have some published information on the Big-Oh Complexity of immutable collections to better understand their performance, but unfortunately, such data seems to be elusive.