It's funny that you phrase this as such, because this exact kind of simple geometry is my go-to example for why this stuff is
not as simple. Let's look at a square. Everyone knows a square is a rectangle, right? So of course a square should extend from a rectangle.
But math doesn't deal with mutability all that much. It's interested in the visible properties and constraints. A square is a rectangle because it meets all the constraints and has all the properties of a rectangle. But that is no longer true if the shapes are mutable. A rectangle might appropriately have `setWidth` and `setHeight` operations. A square cannot implement these operations and still obey Liskov substitution, without the ability to downgrade its type to a rectangle. In OOP you might correct this by making the square immutable and the `setWidth` and `setHeight` operations would return a rectangle instead of a square.
To bring this specifically to this use case: Yes, it's a defined mathematical operation to scale a shape such as a square on the x-axis. But, if you do, that square is now a rectangle. This may be important to the implementation, it may not. But it's certainly a relevant technical concern.