Lifetime Diagrams

Recall from the last section that we had this interaction with Racket:

> (define x 2) 
> (define add1 (lambda (y) (+ 1 y))) 
> (add1 x)
3
> x 
2 
> y 
y: undefined;

Let’s run through this step by step and see exactly what happens:

  • is defined and given a value
  • The add1 function is created
  • add1 is called
  • Variable y is created
  • The argument (contents of x) are copied into y
  • The body (+ 1 y) is executed
  • y is thrown away

This means that y has a limited “lifetime”; x still exists because it is a global variable. We can visualise this using Lifetime Diagrams as in the figure below:

A Lifetime Diagram showing when functions and variables exist.

The top red line shows how long Racket is running. Once we define x, it becomes part of the language and stays in existence until Racket finishes, as does add1, which comes into existence shortly after x. However, y has a limited lifetime because it only exists while add1 is executing; that is, as soon as add1 is finished, y no longer exists.

However, what happens if two copies of add1 are running at the same time? Clearly, they can’t both use y, otherwise they could give the wrong result, so each has its own y. This is often denoted by appending a dollar sign and random number to the variable name, for example y$1231 or y$1831. This shows that it is a local copy of y, but clearly shows that it is a different variable. So, if we had two copies running, a more precise version of the diagram above would be this:

A Lifetime Diagram with multiple copies of the same function running.