I've written about [this explanation of tensors](https://pixel-druid.com/articles/tensor-is-a-thing-that-tran...) before, and it seems worthwhile to write it down again:

There are two ways of using linear maps in the context of physics. One is as a thing that acts on the space . The other is a thing that acts on the coordinates . So when we talk about transformations in tensor analysis, we're talking about coordinate transformatios , not space transformations . Suppose I implement a double ended queue using two pointers:

```
struct Queue {int memory, start, end; }
void queue_init(int size) {
memory = malloc(sizeof(int) size);
start = end = memory + (size - 1) / 2;
}
void queue_push_start(int x) { start = x; start--; }
void queue_push_end(int x) { end++; end = x; }
int queue_head() { return start; }
int queue_tail() { return end; }
void queue_deque_head() { start++; }
void queue_deque_tail() { tail--; }
```

See that the state of the queue is technically three numbers, { memory, start, end } (Pointers are just numbers after all). But this is coordinate dependent , as start and end are relative to the location of memory. Now suppose I have a procedure to reallocate the queue size:

```
void queue_realloc(Queue q, int new_size) {
int start_offset = q->memory - q->start;
int end_offset = q->memory - q->end;
int oldmem = q->memory;
q->memory = realloc(q->memory, new_size);
memcpy(q->memory, oldmem + q->start, sizeof(int) * (end_offset - start_offset);
q->start = q->memory + start_offset;
q->end = q->memory - end_offset;
}

```

Notice that when I do this, the values of start and end can be completely different! However, see that the length of the queue, given by (end - start) is invariant : It hasn't changed!

---

In the exact same way, a "tensor" is a collection of numbers that describes something physical with respect to a particular coordinate system (the pointers start and end with respect to the memory coordinate system). "tensor calculus" is a bunch of rules that tell you how the numbers change when one changes coordinate systems (ie, how the pointers start and end change when the pointer memory changes). Some quantities that are computed from tensors are "physical", like the length of the queue, as they are invariant under transformations. Tensor calculus gives a principled way to make sure that the final answers we calculate are "invariant" / "physical" / "real". The actual locations of start and end don't matter, as (end - start) will always be the length of the list!

---

Physicists (and people who write memory allocators) need such elaborate tracking, to keep track of what is "real" and what is "coordinate dependent", since a lot of physics involves crazy coordinate systems , and having ways to know what things are real and what are artefacts of one's coordinate system is invaluable. For a real example, consider the case of singularities of the Schwarzschild solution to GR, where we initially thought there were two singularities, but it later turned out there was only one "real" singularity, and the other singularity was due to a poor choice of coordinate system:

Although there was general consensus that the singularity at r = 0 was a 'genuine' physical singularity, the nature of the singularity at r = rs remained unclear. In 1921 Paul Painlevé and in 1922 Allvar Gullstrand independently produced a metric, a spherically symmetric solution of Einstein's equations, which we now know is coordinate transformation of the Schwarzschild metric, Gullstrand–Painlevé coordinates, in which there was no singularity at r = rs. They, however, did not recognize that their solutions were just coordinate transform