in reply to Re^2: The fallacy of the *requirement* for read-only instance variables.
in thread The fallacy of the *requirement* for read-only instance variables.

Why would a date class have read-only instance vars?

Because that way you can use a Date like a value type (that is, share one object in different contexts without the risk that some other context might change it).

Immutable objects also have the nice property of being sharable among threads without need for any locking.

  • Comment on Re^3: The fallacy of the *requirement* for read-only instance variables.

Replies are listed 'Best First'.
Re^4: The fallacy of the *requirement* for read-only instance variables.
by BrowserUk (Patriarch) on Apr 17, 2011 at 19:20 UTC
    Because that way you can use a Date like a value type (that is, share one object in different contexts without the risk that some other context might change it).

    Outside of threading, what type of "contexts" are there which could "share objects" with a risk that one of them might change it without it being a deliberate act on the part of the programmer to do so?

    And if it is a deliberate act, where is the "risk" you speak of?

    Immutable objects also have the nice property of being shareable among threads without need for any locking.

    You are basically saying that every object should be immutable, and therefore every mutation of an object should results in the allocation and population of a new instance of the object and the old one garbage collected, even in single-threaded code, in order that on those odd occasions when you need to pass an existing object to another thread, you don't have to copy it.

    Copy everything every time you shouldn't have to, so that you don't have to copy the one time you should. Way to go.

    And what is the point in sharing a single immutable object anyway? The point of shared data is it allows communication between the sharing threads which is impossible if it is immutable.

    I know that the concurrent pure functional languages use this mechanism. But they also have the benefit of separate compilation and huge, often slow, deep analysing compilers to allow them to avoid actually copying & garbage collecting their "immutable" entities when they can safely mutated in-place. Basically, the costs of immutability are optimised away under the covers by the compiler. The purity is language level concept, not a runtime one. I've previously referred to this as smoke & mirrors.

    But in a dynamic language, with mutability a fundamental and inherent part of the language design--eg. ++$i etal.--this is a nonsense. Show me one concurrent, dynamic language that has efficient garbage collection?

    To make this schema even vaguely efficient, the optimising analysis would have to be done at load-time, and repeated every time the program is loaded. And you'd have to ban eval and all other forms of runtime loading: do, require.

    At which point, why bother with a dynamic language?

    Sorry, but in the context of Perl, I do not believe that you have thought your immutability arguments through.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Outside of threading, what type of "contexts" are there which could "share objects" with a risk that one of them might change it without it being a deliberate act on the part of the programmer to do so?

      Different lexical scopes, different libraries where you don't know how well they are programmed etc.

      You are basically saying that every object should be immutable

      Not at all. Please stop laying words in my mouth that I didn't utter.

      I'm saying that immutability can be beneficial. Of course it also comes at a cost, so it's a tradeoff. As always.

        different libraries where you don't know how well they are programmed

        Hm. So, you make your date object immutable so that you can safely pass it to library code that you didn't write and know it will not be modified.

        Except that, for the library to accept this data object, it has to be programmed to expect this type of date object or one compatible with it. And if it mutates it, then that should be documented.

        If it isn't and you are concerned, then you can pass in a copy.

        If it is, and you don't want that, you could pass in a copy.

        If it isn't and it does, then that is a bug.

        Again, you are forcing objects to be copied when they needn't be, in order to avoid having to when know you should.

        Please stop laying words in my mouth that I didn't utter.

        You're right. That was badly phrased and I apologise.

        I should have said: What you are implying, knowingly or not, is that every object should be immutable.

        Because the alternative is a hybrid of mutable and immutable objects, that creates far more risk of forgetting to pass a copy when you need to ensure the original remains unmodified; or unnecessarily copying for the same reason.

        Which essentially negates the only benefit: that of not having to copy when you are unsure. That does not seem tenable to me.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

      Outside of threading, what type of "contexts" are there which could "share objects" with a risk that one of them might change it without it being a deliberate act on the part of the programmer to do so?

      Say you have a $price1 object. It might be shared between $item1 and $purchase1. One might change the amount of $price1 in order to change the price of $item1, but that would be wrong, as it would result in the unintentional (not deliberate) act of altering the records of the purchase.

      By limiting the ability to change the amount of $price1 (i.e. making Price immutable), one avoids this type of mistake. (One could also avoid the mistake by not sharing $price1, but that requires more memory.)

      We actually do have a Price class here. It's an overloaded object that has an amount an a currency. It's immutable so this works:

      $y->set_price( $x->get_price() ); my $price = $x->get_price(); $price *= 2; # Creates a new object. $x->set_price( $price );

      There's no deliberate act to change $y, but it would change if Price was mutable.

      Update: Added example.