Чтобы ответить на ваш заглавный вопрос "Использует ли какой-либо язык программирования переменные так, как они используются в математике?": C, C#, Java, C++ и любой другой язык в стиле C использует переменные так, как они используются в математике.
Вам просто нужно использовать == вместо =.
Если я возьму ваш оригинал
root(square(x)) = abs(x)
Тогда я могу перевести его в C# напрямую без каких-либо изменений, кроме синтаксиса.
Math.Sqrt(Math.Pow(x,2)) == Math.Abs(x)
Это будет иметь значение true для любого значения x до тех пор, пока квадрат x меньше максимального значения для используемого типа данных. (Java будет во многом похожа, но я полагаю, что пространство имен Math немного отличается).
Этот следующий бит не скомпилируется в C#, потому что компилятор достаточно умен, чтобы понять, что я не могу присвоить возврат одной операции другой операции.
Math.Sqrt(Math.Pow(x,2)) = Math.Abs(x)
Неизменяемость не имеет к этому никакого отношения. Вам все равно нужно присвоить значение в неизменяемом языке, и вполне возможно, что данный язык может решить сделать это, используя = в качестве оператора.
В подтверждение сказанного, этот цикл будет выполняться до тех пор, пока вы не исчерпаете допустимые значения x и не получите исключение о переполнении:
while (Math.Sqrt(Math.Pow(x, 2)) == Math.Abs(x))
{
++x;
System.Console.WriteLine(x);
}
Вот почему математики ненавидят использование = для присваивания. Это сбивает их с толку. Я думаю, что это привело к тому, что вы запутались сами. Возьмем ваш пример
y = (x**2)**.5
x *= 2
assert y == abs(x)
Когда я перевожу это в алгебру, я получаю следующее:
abs(2x) = root(x^2)
Что, конечно, не верно для значений, отличных от 0. Неизменяемость только спасает вас от ошибки изменения значения x, когда вы добавляете дополнительные шаги между оценкой левой и правой частей исходного уравнения. На самом деле она не меняет того, как вы оцениваете выражение.
Прикрепляю к посту несколько видео по теме: