I'm from an extremely pure and extremist OOP background, and my OOP designs tend to be 99% immutable objects (Even in languages which allow mutation). If you have a pipeline of functions where each function is supposed to add or update data in a record, in my experience, each function will deal with a subproblem and subconcept of that record, so you should create a class/type/whatever for each of those to follow OOP best practices like SRP, SoC. If any class/record/type has more than 4 or 5 fields/variables/attributes I think you are probably putting too much responsibility there. If you split the problem into several subproblems, each function of your pipline will create a sub record of the record, and the main function will just combine them all to create the main record. In my experience following traditional OOP drives you to a design that will allow you to achive what you want to achive without any mutation.