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.

Daniel Lemire, "Are your strings immutable?," in Daniel Lemire's blog, July 7, 2017.

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

12 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

    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 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

  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.

  4. Why are Python strings immutable? Which means a string value cannot be updated . Immutability is a clean and efficient solution to concurrent access. Having immutable variables means that no matter how many times the method is called with the same variable/value, the output will always be the same. Having mutable variables means that calling the same method with the same variables may not guarantee the same output, because the variable can be mutated at any time by another method or perhaps, another thread, and that is where you start to go crazy debugging.

    1. Python implements a *lot* of Python using strings and dictionaries. Having strings be immutable means that many optimizations, like caching the hash value of a string, interning strings, etc. remain cheap and easy. This leads to surprisingly good performance in places where you might expect to find bad performance.

      The “cost” of this, in Python, appears to be that inefficient string construction is part of learning the language. ISTR that “my ” + “dog ” + “Spot” would be parsed as an intermediate binary sum then another sum, resulting in a “my dog ” or maybe “dog Spot” being created and abandoned. I’m out of touch, so the state of the art has likely improved, but there were other weirdnesses about optimization that the compiler wouldn’t do, for whatever reasons. Price of a dynamic language, I guess.

  5. Everything in Python is an object . You have to understand that Python represents all its data as objects. An object’s mutability is determined by its type. Some of these objects like lists and dictionaries are mutable , meaning you can change their content without changing their identity. Other objects like integers, floats, strings and tuples are objects that can not be changed.

    Strings are Immutable

    Strings are immutable in Python, which means you cannot change an existing string. The best you can do is create a new string that is a variation on the original.

    1. You could use the StringIO Module which is pretty much the same as the Java StringBuffer Class. Such objects are mutable.

Leave a Reply

Your email address will not be published.

You may subscribe to this blog by email.