Объяснение того, почему (большинство) языков программирования нарушают коммутативный закон сложения

Все знают, что a+b = b+a, верно? Это то, что мы знаем из начальной школы, и это вполне разумно. Если я дам вам 3 яблока, а затем 2 яблока, это то же самое, если бы я дал вам сначала 2 яблока, а затем 3.

Конечно, когда вы проходите свой первый курс линейной алгебры, вы узнаете, что это не всегда так в случае умножения. В матрицах одно из первых свойств, которое вы изучаете, заключается в том, что обычно A ⋅ B ≠ B ⋅ A, или, как сказал бы математик, умножение не является коммутативным.

Я не посещал занятия по теории групп, но, судя по тому, что я искал, некоммутативное сложение на самом деле встречается очень редко. Поэтому, когда я услышал, что сложение может быть некоммутативным в программировании, это казалось таким неестественным. После некоторых размышлений, конечно, это логично. Давайте посмотрим на пример на C. Мы начнем с определения 2 функций, f и g, и глобальной переменной «Global_var».

int Global_var = 1;
int f(int x){
   Global_var++;
   return x + Global_var;
}
int g(int x){
   return x + Global_var;
}

Чему равно f(1)+g(1)? Сначала Global_var становится равным 2, а f(1) возвращает 3, после чего g(1) возвращает 1+2 = 3, поэтому f(1)+g(1) = 3 + 3 = 6.

Давайте посмотрим, чему равно g(1) + f(1). Global_var равен 1, поэтому g(1) возвращает 2 . Переходя теперь к f(1), Global_var станет 2, поэтому f(1) вернет 1+2=3 . Результатом будет g(1)+f(1) =2+3 = 5 .

Вывод? f(1)+g(1) ≠ g(1) + f(1)

Здесь вы можете задать вопрос: почему большинство?

Объяснение того, почему (большинство) языков программирования нарушают коммутативный закон сложения

Почему я написал на подзаголовок больше всего?

Ключ — неизменяемые объявления. В Haskell и некоторых других языках объявление неизменяемости означает, что когда вы объявляете переменную, вы не можете изменить переменную снова. Global_var++; часть просто не будет иметь никакого смысла.

Вышеупомянутая проблема возникла из-за того, что g(1) == 3 в первом примере, а во втором g(1) == 2. В старшей школе мы узнали, что функции не меняются с течением времени. f(x) с одним и тем же входом всегда будет иметь один и тот же результат, несмотря ни на что. Но, как мы видели в приведенном примере, языки программирования не всегда ведут себя как наша «традиционная» математика.

Вы можете найти статью о разнице между функциями Математика и Программирование здесь.

Я нигде не могу найти, что если объекты языка неизменяемы, некоммутативность сложения устраняется, но я твердо верю, что это так. Я буду очень признателен, если кто-то может предоставить мне доказательство (или где-то, что оно утверждает это) или, конечно же, контрпример.

Я пишу, потому что хочу общаться со своими читателями и учиться у них. Если кто-то из вас хочет что-то добавить, не стесняйтесь комментировать ниже.