The let keyword creates a name binding, which means "this name means this value" (or this function). It is immutable: in the code you wrote, the name z in the split function will always refer to the value abs(x / 10), and cannot be changed. The let z = z + 1 expression in your if modz > 5 = ... block is not reassigning the value of the outer z. Instead, it's creating a new definition of z, local to the block that it's in. What the code you've written is saying is "within the true part of this if expression, I want a name called z whose value is the value of z that I currently know about, plus 1. Oh, and hide the "outer" z from me: inside this block, I want to use my definition of z." But outside the block, the "outer" z is unchanged. This allows you to redefine names at will, without accidentally causing bugs in other code, and it's usually a good thing.
What you're trying to do is create a mutable variable, and that's done by adding the mutable keyword to let. The syntax for assigning a new value to a mutable variable is also different: it doesn't use let at all. What you wanted is to write:
let mutable z = abs(x / 10)
// Later on...
z <- z + 1
The left-facing arrow operator <- means "change the value of this mutable variable". If you write z = z + 1, which is a common newbie mistake, the compiler will give you a warning that this is a Boolean value that is ignored -- because when it's not part of a let binding, the = operator is comparison. The expression z = z + 1 is asking "is z equal to z + 1?" And that will always be false (unless you've created a really weird numeric type).
I don't really recommend using mutable as a general rule. Try re-writing your logic to avoid it. For example, you could write your function like so:
let split x =
let z = abs(x / 10)
let modz = abs(x % 10)
let increment = if modz > 5 then 1 else 0
let y = if modz > 5 then abs(5 - modz) else modz
(y, z + increment)
That would be more functional, and avoid the use of mutable.