Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.
Побочные эффекты в программировании
Сегодня в моём философском разделе поговорим о таком вопросе, как побочные эффекты в программировании.
Общие замечания
Побочные эффекты (далее ПБЭ) - интересный вопрос. Он интересен и для программирования и для обучения программированию. Во всяком случае можно встретить рассуждения, где ПБЭ привязывают к тому, с какого языка следует обучать программированию.
Побочные эффекты могут вызывать ошибки при работе программы. Если программист грамотно учитывает наличие ПБЭ, то ошибок не возникает. Т.е. ПБЭ это не хорошо и не плохо, это просто явление, которое нужно знать.
Что такое побочные эффекты в программировании
Прежде чем определиться с тем, что такое ПБЭ, введем такое понятие, как среда выполнения программы. Если говорить в общем, то это все то, что влияет на выполнение программного кода. Представим себе фрагмент кода и зададим себе вопрос, как его выполнение может повлиять на работу программы. На что может повлиять выполнение этого фрагмента в общем случае?
- Значение глобальных переменных.
- Содержимое файлов и баз данных.
- Работа с памятью.
- На состояние внешних устройств и программ.
Все это может воздействовать на дальнейшее выполнение программы или на ее выполнение при повторном запуске. Если программа в каком-то месте изменила глобальные переменные, которые используются в другом месте программы (или в том же при повторном прохождении), то не корректность алгоритма может привести к очень трудно отлавливаемым ошибкам. Например, ошибкам, которые проявляются с не большой вероятностью. Иногда чрезвычайно сложно понять логику проявления таких ошибок.
Но это еще не все. Суть в том, что сам код может содержать в себе некоторые неоднозначные вещи, когда его исполнение может быть по-разному реализовано разными версиями трансляторов.
Типичный пример для языка C
ar[++i] = i;
Порядок вычисления этого выражения абсолютно не известен. Он не оговорен в стандарте, а как это решит для себя конкретный компилятор - не ясно. Перекомпилировали программу другой версией компилятора и вдруг программа перестала корректно работать. Такие ошибки искать бывает не легко. А возьмите выражения, когда содержащаяся там переменная, сама меняется в процессе вычисления. Например
a = (i *n) + j * (i++);
Чрезвычайно опасное выражение, потому как разные компиляторы по-разному могут его интерпретировать.
Есть также побочные эффекты, связанные с тем, что разные процессоры могут по-разному обрабатывать операции с вещественными числами.
Я бы разделил побочные эффекты на два типа: ПБЭ в широком смысле и ПБЭ в узком смысле. В первом случае это любой фрагмент программы, который меняет среду выполнения программы. Во втором случае речь идет о побочных эффектах внутри одного выражения.
В связи с ПБЭ вводятся так называемые точки следования. Такими точками называют места в программе, когда все предыдущие побочные явления уже проявились. Точка следования может быть и внутри выражения. Например
f = a() + b() + c()
Если в языке программирования установлен порядок вычисления такого выражения (например слева направо), то знак сложения можно считать точкой следования. А если нет, то мы имеем источник ПБЭ. Например, в случае, когда одна функция меняет глобальные переменные, а другая их использует.
Вообще, наличие функции внутри выражения может быть тем самым побочным эффектом. Выражение f = a() + b() + c() содержит три функции. Вычисление каждой из них может влиять на вычисление другой. Обычно предлагается разбить подобное выражение на несколько
f1 = a()
f2 = b()
f3 = c()
f = f1 + f2 + f3
И смысл в этом есть. После каждого вычисления можно проверить и сам результат и состояние среды программирования.
Побочные эффекты и с какого языка обучать программированию
Язык считается более строгим, если в нем мало побочных эффектов. Скажем язык Pascal в этом смысле более строг чем C или C++.
Типичный пример для сравнения:
a:=10
для Паскаля это только лишь оператор присвоения, а в Си
a=10
является выражением, которое может входить в другое более сложное выражение. Можно вспомнить аналогичное выражение в Python: a := 10, которое также может входить в другое выражение.
И вот тут возникает интересная дилемма. А какой язык программирования выбрать для первого знакомства: более строгий или менее строгий.
Есть устоявшееся мнение, что выбирать нужно более строгий язык. Якобы он приучает начинающего программировать к более правильным манерам в программировании. Я не очень согласен с таким подходом. Если человек научился (его научили) корректно программировать, скажем, на языке C, то тем более у него не будет проблем с более строгим языком. А вот обратное совсем даже не очевидно.
Я то лично вообще придерживаюсь того мнения, что начинать можно с любого языка. Главное это выработка алгоритмического мышления. А стиль можно отрабатывать на любом языке.
Я понимаю, что мне сейчас будут возражать. Что учить надо хорошему стилю и с помощью правильного языка. Ну я всегда против этого возражал. Но тут есть один нюанс: а какую задачу мы ставим?
Пока всё!
Пишите свои предложения и замечания, и занимайтесь программированием, а также проектированием баз данных, хотя бы для поддержания уровня интеллекта.