Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You can’t separate out immutability because without immutability it’s not functional code, it’s just procedural code.

To the question of consistency though, OOP gets you very little because consistency rarely maps directly to objects. So if you end in a situation where object A is inconsistent with the object B, you still have to trace out all the locations where object A and object B might have been mutated and figure out what combination of code causes the issue.

At least in the global state system you can get runtime consistency by running consistency checks on each attempted transaction.



There are two types of "data" in a properly encapsulated class [1]:

1. Internal/private data -- things like a pointer to a string's contents, its length, and the capacity of the content buffer.

2. Public "data" (API) -- best provided as accessor methods/properties (and public methods) to ensure that the class' invariants hold if these can be used to mutate state. You don't care if the object has been mutated through this public API as this is the contract for how the class/object instances should be used.

A properly encapsulated string class is free to change its internal state/data (e.g. start+length+capacity, or start+end+endOfBuffer), as long as it keeps the contract defined by the public API intact. The same applies for data structures, mathematical objects like complex and rational numbers.

You could store a complex number in polar (r, theta) or cartesian (x, y) form and provide public accessors for all of those values. If you had setters for those, the native representation would be a simple assignment, while the other representation would do the necessary polar <=> cartesian conversion. This would maintain the invariant that the two representations are equivalent, such that if you set r then the angle (theta) does not change, but the magnitude changes such that it is equal to r.

Note that if the complex number (or string) was modelled in a procedural or functional language, you would have to choose and stick to one or the other representation. That structure or type definition is leaking the state, such that a program could modify the length of the string without updating its contents.

Q: Can you give an example of where having object A inconsistent with object B is an issue? That would help me to understand the issue/problem you are referencing.

[1] Many OOP languages also allow protected data, which can be seen by implementations but not any other code. These are risky, as they can allow the derived class to break any invariants on that protected data like you described in your second paragraph. As such, I try to avoid them wherever possible in my own code, but will run into them in thirdparty or system classes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: