Are your strings immutable?

A value is immutable if it cannot change.

Immutability is a distinct notion than that of a constant. The speed of light in a vacuum is believed to be a universal constant, for example. Constants are immutable in the sense that they cannot change. However, immutability refers to values, not to the assignment of values. For example, the number 3 is immutable. However, if I say that your rank is 3, this rank could change. That’s because your rank is a variable, and variables may change their values even if these values are immutable.

That is, a variable may change its value to point to a different immutable value. That’s a somewhat confusing point for non-programmers. For example, my name is “Daniel”. To say that strings are immutable is to say that I cannot change the string “Daniel”. However, I can certainly go see the government and have my first name changed so that it is “Jack”. Yet this change does not modify the string “Daniel”. If I could change the string “Daniel” then, possibly, all individuals named “Daniel” would see their name changed.

So in the world around us, values are typically immutable. And that’s largely why it is believed that immutable values are safer and easier.

Working with mutable values requires more experience and more care. For example, not only does changing the string “Daniel” affect all people named “Daniel”, but what if two people try to change the string at the same time?

So integer values are always immutable, not only in real life but also in software. There is no programming language where you can redefine the value “3” to be equal to “5”.

Yet I believe that most programming languages in widespread use have mutable arrays. That is, once you have created an array of values, you can always change any one of the entries. Why is that? Because immutability could get costly as any change to an immutable array would need to be implemented as a copy.

Arguably, the most important non-numeric type in software is the string. A string can be viewed as an array of characters so it would not be unreasonable to make it mutable, but strings are also viewed as primitive values (e.g., we don’t think of “Daniel” as an array of 6 characters). Consequently, some languages have immutable strings, others have mutable strings. Do you know whether the strings in your favorite language are mutable?

  • In Java, C#, JavaScript, Python and Go, strings are immutable. Furthermore, Java, C#, JavaScript and Go have the notion of a constant: a “variable” that cannot be reassigned. (I am unsure how well constants are implemented and supported in JavaScript, however.)
  • In Ruby and PHP, strings are mutable.
  • The C language does not really have string objects per se. However, we commonly represent strings as a pointer char *. In general, C strings are mutable. The C++ language has its own string class. It is mutable.

    In both C and C++, string constants (declared with the const qualifier) are immutable, but you can easily “cast away” the const qualifier, so the immutability is weakly enforced.

  • In Swift, strings are mutable.

    However, if you declare a string to be a constant (keyword let), then it is immutable.

7 thoughts on “Are your strings immutable?”

  1. Concerning: “There is no programming language where you can redefine the value “3” to be equal to “5”.”

    Well, there was such a programming language where you might have been able to do so: Fortran-77.

    I don’t know if it is still like this (I wrote a program with this bug in 1985), but here is a “bug” I once had, written in pseudo-FORTRAN code:

    DEF INC( X )
    X = X + 1
    END

    INC( 0 )
    PRINT *, 0

    This program prints “1” on stdout (*)!

    Why? Because in Fortran-77, all arguments are passed by reference. When 0 is used as argument in the call to INC, what is passed as real argument is a reference to the location in the *constant table* where 0 is stored. The location’s content is then increased by 1 in INC, an so 0 becomes 1.

    1. As I understand it, that was non-conformant compiler behavior, not part of the Fortran specification. See http://computer-programming-forum.com/49-fortran/c1e8b7d194d9f46a.htm for elaboration, where one commentor quotes from the FORTRAN 66 specification then adds “All Fortran standards have required that actual arguments be
      definable if they are associated with dummy arguments that
      change during the execution of the procedure. It is not, however,
      a violation that’s required to be detected or reported by compliant
      implementations.”.

  2. Regarding the “redefining the value of 3 to be 5”, in Java and C#, you can use an Aspect Weaver to do this. In addition, in Java, you can mess with the Integer constant pool (using reflection + trickery) to set the third value to 5, which means Integer.valueOf(3) will return an Integer instance with a value of 5. Finally, observe the following forth code:

    :3 5;

    Regarding String immutability, in Rust, Strings are mutable, but one often uses a mutable &str slice instead of the raw value.

      1. There are different types of strings in Rust: some of them are mutable.
        std::string::String is like C++’s std::string – an owned mutable buffer.
        &str is a immutable view of a (sub-)string (Rust’s type system also guarantees that noone can change the string while you inspect it through &str).

  3. Keep in mind that casting-away constness of values in C and C++ is undefined behavior if the value was originally defined as const. This means that, for example, casting away constness inside a function where you don’t really know the origin of all the arguments may be unsafe.

    This isn’t just a language-ism that has no practical consequence: modern compilers are putting objects (including const char* values and string objects) inside the “read only” section (e.g., .rodata) of the executable, which are mapped read-only into the process, and so actually cannot be written. This applies also to string literals in both languages.

    So as a practical matter, your program will probably crash if you try to write a string literal or a string declared as const.

Leave a Reply

Your email address will not be published. Required fields are marked *