I'll leave it to the experts to list all the advantages of immutable data structures, but I've seen why we needed a similar compartmentalisation in HTML::FormHandler. The FormHandler form object is reusable, you can use it to validate many parameter hashes. We started coding it as a mutable object and storing all the changing values in the form object itself, the first problem was that we kept forgetting to reset them at the start of processing of new data. This lead to many subtle bugs, sometimes difficult to track so we started to just recreate the form object for each processing run. This worked OK, because the form object itself was not that heavy to create until someone had a form object that contained other heavy object and recreating it would require recreating them. So eventually we separated all the state that changes during the processing into a separate
Result
object, now to clean the form state we need to recreate only that separate object.It needs to be stated clearly that this separation of immutability is a trade-off (as always) - it is an additional requirement so it increases the complexity of the code and means for example that the
$self
object in controller actions is underused - because actions should not change it's state (including storing something in it's attributes). Certainly it is not feasible to make such change now and this also would be a trade-off but for the sake of exercising imagination: maybe actions could be methods on the changing part (and not on the controller object) and only use the controller object in some way - this way all the basic code (like that from the Manual) would use $self
object in the way common to object oriented code.
1 comment:
In general I agree that mutability is often associated with messy and low performance code, which is why I think catalyst controller are designed to be immutable and why the current Stash is the main method of containing request state.
As you probably know, I'm not a fan of the stash, although as part of my conversation on the matter I've seen some ideas that make it more palatable. For me, I'm leaning toward a group of ideas to help reduce the need for the stash. For example, if you want a nice place to hang request associated attributes, I'm thinking why not just make it easy to apply custom traits to the Catalyst::Request and put them there? I'll blog it shortly, but I think there's a lot of options on the table (some of them actually good :) )
Post a Comment