Learning Objectives
After this section you will be able to:
- Explain what problem limits solve — why plugging in a number is sometimes forbidden but an answer still exists.
- Read the notation in plain English.
- Approximate a limit from a numerical table and from an interactive graph.
- Detect when a limit fails to exist (jump, oscillation, blow-up).
- Connect limits to the derivative by watching a secant slope converge.
- Compute a simple limit in Python and in PyTorch.
The Problem That Birthed Calculus
How fast are you going right now? Not between two moments — right now, at a single instant.
Speed is distance divided by time. That is the definition from primary school: . But what happens when is zero? Distance travelled in zero time is zero. We are asked to compute . Our arithmetic cannot do this.
And yet a speedometer reads something — a definite number — at every instant. Cars and planets move with an instantaneous speed even though the formula breaks down. Physics insists the number exists. Algebra insists the computation is illegal. Who is right?
The Calculus Question
Can we give a rigorous meaning to “the value a quantity is heading toward” even when plugging in the target itself is forbidden?
The answer calculus invented is called a limit. It is a new kind of “value” — not the output of a formula at a point, but the target the output approaches as we slide toward that point. Every derivative, every integral, every differential equation in this book rests on this one idea. Let us build it carefully.
The Hole in the Graph
To make the idea concrete, throw away the motion story for a moment and just stare at a formula:
Plug in any number you like: gives , gives , gives . Every value works — except . There both the numerator and denominator vanish, and we are handed — a meaningless expression.
The graph of this function looks exactly like the straight line — except for a tiny infinitesimal puncture at the single point . The line is whole everywhere else; only this one point is missing.
Why x + 1?
Factor the numerator: . Then whenever we are allowed to cancel — i.e., whenever . At the cancellation is illegal (it would be dividing zero by itself), so the function stays undefined there. The hole is real; it is not an artifact of bad algebra.
So here is the puzzle. The graph is a straight line with one missing point. Every neighbour of gives an output you can almost predict — values just below 1 produce outputs just below 2, values just above 1 produce outputs just above 2. The function is pointing at the value 2 from both sides. It just never arrives.
The limit is our formal name for “the value the function is pointing at.” Let us see it live.
Zoom Into the Hole — Interactive
Drag the slider. The window around narrows by a factor of ten every decade. The function is plotted in indigo; the orange/teal dots are probes moving with the zoom. The white circle at marks the hole — it is genuinely empty, no matter how far you zoom in.
What the zoom is telling you
No matter how much you magnify, the two probes always sit symmetrically around a single point on the graph, and that point is always one unit above the line scaled with the zoom. In absolute terms, both probe readings sit within a distance roughly equal to the current window half-width of the target value . As , those readings become indistinguishable from 2.
The Numerical Table Approach
Before the formal definition, Leibniz and the Bernoullis convinced themselves that limits made sense by computing. Given a function and a target input, they built a table of outputs at nearby inputs and watched for convergence. We do the same here:
| x (approach from left) | f(x) | x (approach from right) | f(x) |
|---|---|---|---|
| 0.9 | 1.9 | 1.1 | 2.1 |
| 0.99 | 1.99 | 1.01 | 2.01 |
| 0.999 | 1.999 | 1.001 | 2.001 |
| 0.9999 | 1.9999 | 1.0001 | 2.0001 |
| 0.99999 | 1.99999 | 1.00001 | 2.00001 |
| ↓ | ↓ | ↓ | ↓ |
| 1 (forbidden) | undefined | 1 (forbidden) | undefined |
Left column: outputs are climbing toward 2 from below. Right column: outputs are descending toward 2 from above. The function does not attain the value 2 (because the inputs never attain 1). But both columns leave no doubt about the target.
Calculus captures this observation with a single piece of notation:
Read aloud: “the limit, as approaches 1, of , equals 2.” The arrow is the important symbol — it means approaching but never reaching. The equation is not claiming (that is false — is undefined). It is claiming something subtler and stronger: that the outputs line up arbitrarily close to 2 whenever the inputs line up arbitrarily close to 1.
The Intuitive Definition of a Limit
Working Definition (intuitive)
We write to mean: we can make as close to as we please — within any tolerance you demand — by choosing close enough to (but not equal to ).
Three pieces of this sentence deserve emphasis.
- “As close as we please”. No tolerance is too small. Name any positive number — a billionth, a trillionth, — and we must be able to place within of .
- “By choosing x close enough”. For every such tolerance, there is a distance around that does the job. Small typically demands small .
- “But not equal to a”. The value of at is irrelevant. It might be undefined, or defined but wrong (think of a graph with a single filled dot floating above the line). The limit only cares about neighbours of .
This is the language that will become the formal - definition in §2.5. For now, hold onto the metaphor: you (the challenger) pick a tolerance around ; the function (the responder) must guarantee a matching window around . If it can always respond, the limit equals .
Worked Example — Factoring the 0/0
Before we trust any software, let us compute the same limit by hand. The trick is to break the spell of by factoring.
Click to expand — step-by-step calculation of
The symbol is called an indeterminate form. It does not mean the limit doesn't exist — it just means direct substitution is not enough to find it.
We do not cancel at itself — division by zero is still illegal there. But the limit only cares about near 1, not , so the cancellation is legitimate inside the limit.
The function is a polynomial; it is defined at 1 (value 2) and substitution IS valid for polynomials. So the simplified limit is exactly 2.
This matches the numerical table, the zoom visualization, and common sense. The function has a hole at , but it wants to be 2 there — and the limit gives us the formal right to say so.
When the Limit Does Not Exist
The limit of our factoring example worked because both one-sided “targets” agreed. What if they don't? Four things can go wrong, and it is worth recognising each one.
- Jump. The two sides approach different numbers. For the sign function, while . No single can satisfy the definition.
- Blow-up. The values grow without bound near . For , both one-sided outputs head off toward . No finite exists, though we write as shorthand.
- Wild oscillation. The function bounces arbitrarily fast near . The canonical example is ; every neighbourhood of 1 contains values arbitrarily close to and . There is no single target.
- Undefined on one side. e.g., near has no left-sided limit (no real square root for negative inputs).
The rule of the two sides
The two-sided limit exists and equals if and only if both one-sided limits exist and equal . If either side misbehaves, the two-sided limit fails. We will revisit one-sided limits formally in §2.2.
Left vs. Right — Interactive
Four scenarios, one probe on each side. Use the buttons to switch and the slider to shrink the probe distance . Watch when the two sides agree and when they do not.
Python: Computing the Limit by Brute Force
The table we stared at earlier was hand-computed. Let us do the same thing in Python, so the student can paste this into a REPL or notebook and watch the convergence live. Click any line of the code to see the exact values flowing through it.
The output prints a table that squeezes onto 2 from both sides, and the last three lines confirm that really does raise ZeroDivisionError. The limit exists; the function value does not. These are two different things, and Python made the distinction painfully obvious.
PyTorch: Limits as Vectorised Evaluation
Pure Python required a for-loop. PyTorch lets us evaluate at many probe points in a single tensor operation. More importantly, we get a first glimpse of autograd — PyTorch's automatic-differentiation engine, which is nothing more than a limit machinery implemented in C++.
Why this matters later
Every time you call loss.backward() in a neural-network training loop, PyTorch is computing millions of limits on your behalf. They are the same limits you just saw — just executed by the chain rule at every parameter. Nothing in that backward pass can be understood without the idea developed in this section.
Seeding the Derivative — Interactive
We started with a physics question we could not answer: what is the instantaneous speed of a moving object? Let us close the loop and answer it — at least for one specific curve.
Consider the parabola at . Its slope there is well-defined in principle but there is no “rise-over-run” formula that works at a single point — the run would be zero. The trick is the same trick we just invented: approach the point with a secant line and take the limit of its slope.
The slope of the secant through and is, after a tiny algebra check,
and so . The number 2 is the tangent slope at — our first derivative, computed with nothing more than the limit idea.
Drag all the way down. The secant (in orange) rotates onto the tangent (the dashed grey line) and the displayed slope converges to 2 from above. This is the picture behind every derivative in Chapter 4 — and, by extension, every gradient in gradient descent.
Common Pitfalls
- Confusing with . They are independent. The limit can exist when does not; they can also disagree (think of a graph with a single misplaced dot). The limit is about trend, not evaluation.
- Treating 0/0 as 0 or as 1. is an indeterminate form. It is a flag that says “do more work” — factor, rationalise, apply L'Hôpital — not a shortcut to an answer.
- Using a finite sample as proof. Our numerical table suggests but does not prove it. Floating-point arithmetic can mislead: tables for near 0 can look like they converge to any value you like, depending on where you sample. The formal definition (next sections) is what forbids that trap.
- Forgetting that both sides must agree. A left-only approach is not a limit. When a function has a natural boundary — a square root at zero, a log at a negative input — the two-sided limit simply does not exist there.
Summary
- The limit formalises the intuition of “the value a function is heading toward,” even when the function is not defined at the target.
- means: for any tolerance there is a neighbourhood of on which stays within of .
- The two-sided limit exists iff the left and right limits exist and agree.
- Limits fail to exist through jumps, blow-up, wild oscillation, or one-sided domains.
- The derivative is a limit (of a secant slope). Autograd evaluates it for us symbolically; the underlying mathematics is exactly what we practiced here.
What's next
§2.2 formalises one-sided limits and jump discontinuities. §2.5 returns with the full - definition and proves the table intuition rigorous.