April 1st, 2007

with Cat The Cat

А еще про программирование напишу.

Вот с этой подачи.

То, что у обычных людей называется стереотипами, у программистов называется инвариантами. И те, и другие позволяют сократить цепочку логических рассуждений в различных ситуациях.

Полезность и тех, и других оценивается достаточно просто: как часто они нам помогают.

Помогают редко - неудобны. Помогают часто - удобны.

И уж когда удобны, отказаться от них нет никакой возможности. Это одно из основных свойств так называемых "старых пердунов."

Стереотипов я касаться не буду, это многие делают лучше меня. Мне гораздо интересней инварианты, поскольку лучше меня к ним притрагиваются пока не очень многие.

Даже более того, меня интересует ровно один инвариант: какой порядок вычислений использовать, ленивый или энергичный. И его нарушение.

Сперва разберемся с нарушением.

Карта местности здесь очень проста: одни части программы используют один подход, неважно, какой, другие - другой. На русский язык это можно перевести, как если бы в одной стране одни области разрешали правостороннее движение, а другие - левостороннее. Даже для пассажира это может пройти не очень гладко, что говорить про водителей.

Приведенная ассоциация полезна: попробуйте представить себе границу областей с плотным транспортным потоком и с разными предпочтительными сторонами движения. Без транспортной развязки на границе облестей не обойтись. Точно такая же конструкция будет необходима и в программе, в виде обвязок. Накладные расходы.

Есть, правда, люди, которым это нравится. Которые любят строить транспортные развязки, писать много кода... Это же все хорошо видно и этим можно бравировать. Но это не про меня и, надеюсь, не про читателей этого опуса.

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

Это плавно подводит нас к выбору основного порядка вычислений.

В принципе, здесь я мог бы и остановиться, поскольку всем известно, какой подход я считаю более удобным, но я все же перечислю парочку-троечку аргументов "за."

Хотя мне и лениво. ;)

Начну с упоминания обычных условных конструкций. Ага, if then else. Которые не вычисляют одну из ветвей, если условие (не) выполняется. То есть, действуя лениво, не делая лишних движений. Это справедливо практически для всех языков программирования.

Ленивый порядок вычислений способствует повышению модульности.

Да и вообще, если у выражения есть вычислимый результат, то единственный способ всегда его вычислить, это применяя ленивый порядок вычислений.

В общем и целом, ЛПВ накладывает меньше ограничений на программиста.

Поэтому лучше всегда использовать ленивый порядок вычислений, переходя на энергичный только тогда, когда деваться некуда. И тщательно изолируя эти места малым количеством переходников.