Ya know the more I reflect on the languages I know the more I realize that outside of functional languages none of them really handle immutability well.

Consider that you want most of your objects to be immutable most of the time. Thats all well and good till you realize you want to be able to edit the objects in such a way that it creates duplicates that have some data changed but are likewise immutable.

This tends to stop working, almost entierly, once you get into subclassing. If you parent class has a method that returns a copy of itself with some data modified, this will break in children classes, since you want children classes to return instances of itself, not its parent.

Its not that you cant fix that, but the code gets very ugly very quickly. Generally you are forced to let the code handling the classes do the copying and editing itself, but that is pretty ugly too.

I have had this pattern problem in almost every OO language i messed with, Java, Ruby, Python, etc.

@freemo Eiffel language manages immutable types in a rather good way. They are called "expanded" in the Eiffel jargon, but you can think to them as "value" instead of "references/entities". So, you have no references to them, but only explicit values. The classic example is an INTEGER NUMBER, or a BOOLEAN or a POINT. You cannot change 5 in 10. 5 is a value.

@mzan Thats common for most languages actually where primitive are immutable and passed by value and all other types are passed by reference. This is true for Ruby and Java for example.

Different languages define primitives differently for example in Java strings are immutable but passed by reference so effectively the same as passed by value for these purposes. In ruby however strings are mutable.

Follow

@freemo yes, there are two levels.

At the semantic/logical level, a type can be a value or a reference.

At the implementation level, if the value-object is big, you can store a reference to a shared dictionary of already instantiated immutable-objects. In OOP, this pattern is called Flyweight.

As funny side-note, in Common Lisp, the implementation level can use both an expanden value or a reference. In CL an integer is always an arbitrary long integer. You cannot have an integer overflow. If the integer is "small", then it will be a normal number ending with a 0 (or 1 depending from the implementation) in the last binary digits. If it is a long number, it will be allocated in RAM, and there will be a reference to it.

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.