Concepts / Immutability and String Updates

Immutability and String Updates

A substring is a contiguous piece of a larger string, and substring operations either read a piece out or write a new piece in.

  • Programming

Predicting the Length After an Edit

Many everyday string tasks come down to two questions: which piece of this string do I need to look at, and how do I change one piece without rebuilding everything else? Substring operations are the tools for answering both questions. A substring is a contiguous piece of a larger string, and substring operations either read a piece out or write a new piece in.

What do you think happens?

The string is 'status: pending' (15 characters). You read out the word 'pending' and write 'done' in its place. How many characters long is the new string?

  • 15 characters

  • 12 characters

  • 4 characters

  • It cannot be known without running the code

Reveal answer
Answer:

12 characters

The new string is 'status: done'. The replacement word 'done' has 4 characters, which is 3 fewer than the 7 characters of 'pending', so the total drops from 15 to 12. The replacement does not have to be the same length as the text it replaces.

The Whole String and Its Pieces

Before looking at any individual operation, hold one picture in mind. The string is the whole. A substring operation either takes a piece of the whole out to examine it, or puts a new piece in its place. Each character in the string occupies a position, and a substring is the run of characters that sits between a starting position and an ending point. The diagram below numbers each character of 'status: pending' from 1 for this illustration, and highlights the run that the word 'pending' occupies.

sposition 1tposition 2aposition 3tposition 4uposition 5sposition 6:position 7spaceposition 8pposition 9eposition 10nposition 11dposition 12iposition 13nposition 14gposition 15
Which exact characters does a start position and a length pick out of 'status: pending', and how do those positions line up with the characters?

Read the diagram as an index map. A start position tells you where the piece begins, and a length tells you how many characters to take from there. For 'pending', the piece starts at position 9 and runs for 7 characters, covering positions 9 through 15. Every character outside that range, including the colon and the space, stays where it is when you work with the rest of the string.

Reading a Piece with substr()

The source states that, directly or indirectly, substr() is the operation used to read substrings. Reading means you start with a string, specify the part you want, and receive that part as a new value. The original string is not the thing handed back to you; the extracted piece is.

The phrase directly or indirectly is worth noticing. It signals that you may call substr() yourself, or you may reach it through another operation or library function that does the same job underneath. Either way the concept is the same: extraction of a piece from a larger string. A read leaves the original string as it was. If you extract 'pending' from 'status: pending', the status string still reads 'status: pending' afterward.

Writing a Piece with replace()

The source pairs substr() for reading with replace() for writing. Writing a substring means you take a string, locate a section of it, and substitute different content into that section. The result is a string whose contents have changed in that region, while the rest of the string is carried over. In the status example, the section 'pending' is located and 'done' is substituted in, and the 'status: ' part comes along unchanged.

Read Versus Write Side by Side

Reading and writing are different kinds of work. A read leaves the original string as it was and gives you a piece of it. A write produces a changed version of the string. Keeping that distinction clear prevents a common confusion, which is expecting a read to change the string, or expecting a write to return only the piece you inserted.

substr()readingreturns the piecethe extracted valueoriginal stringleft as it wasreplace()writingreturns the changedstringthe whole string after theeditpiece insertedpart of the new string, notthe resultproducesdoes not alterproducescontains
How do the two operations differ in what they do to the original string and in what they return?

Tracing a Read-Then-Replace Sequence

Now trace the full sequence on a short string. Work through it one step at a time and track the string after each step. The read is the extraction step; the write is the replacement step.

Worked example

Read the state word, then write a new one

Start with the string 'status: pending'. Read out the word that describes the current state, then write the new state word 'done' into that position. What does the string look like after each step?

  1. 1
    Start

    The string is 'status: pending'. Its total length is 15 characters.

  2. 2
    Read the piece

    The read extracts 'pending' from the position where it sits. The extracted value is 'pending', and the original string is still 'status: pending'.

  3. 3
    Write the replacement

    The write locates the section 'pending' and substitutes 'done' into it. The 'status: ' part is carried over unchanged.

  4. 4
    Check the result

    The string is now 'status: done'. Measure it again: it has 12 characters, not 15.

Result

The final string is 'status: done', and the value read out along the way was 'pending'.

status: pendingstartpendingread resultstatus: pendingunchanged after readstatus: doneafter writereadoriginal keptwrite
After reading a substring and then replacing part of the string, what does the string look like at each step?

When the Length Changes

The source states that a string can grow and shrink as needed. This matters for substring writes in particular. The replacement text does not have to be the same length as the text it replaces. If the new piece is longer, the string gets longer. If it is shorter, the string gets shorter. In the status example, 'pending' has 7 characters and 'done' has 4, so the string shrinks by 3 characters.

pending7 charactersstatus: pending15 charactersdone4 charactersstatus: done12 charactersreplaced byrewritten as
Why can the total length of the string change after a replacement, and how does the replaced piece's size compare to the original piece's size?

Mistakes Learners Make With Substring Updates

  • Common mistake

    Expecting a read to change the original string

    What it looks like

    After extracting 'pending' from 'status: pending', assuming the original now reads 'pending' or has changed.

    Why it fails

    A read returns a piece and leaves the original string unchanged.

    Do this instead

    Keep the extracted value and the original string as two separate things. Only a write produces a changed string.

  • Common mistake

    Expecting a write to return only the inserted piece

    What it looks like

    After replacing 'pending' with 'done', expecting the result to be just 'done'.

    Why it fails

    A write produces the changed version of the whole string, so the result is 'status: done'.

    Do this instead

    Read the write result as the full string, with the unchanged parts carried over.

  • Common mistake

    Assuming the length stays the same after a write

    What it looks like

    Assuming 'status: done' still has 15 characters because it replaced 'pending'.

    Why it fails

    The replacement can be shorter or longer than the text it replaces, so the total length can change.

    Do this instead

    Measure the string again after every write before using its length or any position in the rest of the string.

Practice Tracing a Replacement

EASY

Start with the string 'task: running' (13 characters). Read out the word 'running', then write 'halted' into that position. Write down the string after the read, the string after the write, and its new length.

Hints
  • After the read, the original string should still read 'task: running'.
  • The write substitutes 'halted' for 'running' and carries over 'task: '.
  • Count the characters of the final string again rather than reusing the old length of 13.

Key Takeaways

  • A substring is a contiguous piece of a larger string; substring operations either read a piece out or write a new piece in.
  • The source associates substr() with reading substrings and replace() with writing them, directly or through other operations that rely on them.
  • A read returns a piece and leaves the original string unchanged; a write produces a changed string, not just the inserted piece.
  • A string can grow and shrink, so the length after a substring write may differ from the length before it. Measure the string again after each write.

Related concepts

More concepts starting with I