Как писать код? Технологии древних цивилизаций, или все новое - это хорошо забытое старое

Публикация № 987376

Программирование - Теория программирования

программирование код

70
Все современные технологии - это развитие и доведение до ума (или маразма) древних идей. За последнее время не придумали ничего нового - все, что мы видим, было придумано тысячи лет назад. Не является исключением и программирование, которое в сути своей является переводом с языка условностей технического задания или заявки пользователя в формализованный и абсолютно точный язык математической логики. А логику придумали (по крайней мере первыми опубликовались в ведущих научных журналах) еще древние греки.

1. Математика - гимнастика ума.

Как ни крути, но программирование - это математика. Не та математика, где диффуры и прочие пространства Минковского, а вполне себе простая описательная математика функций преобразования одного в другое. Умные люди придумали такое понятие, как "Дискретная математика", которая рассматривает графы и логические утверждения, которые обозваны в ней "Дискретными структурами". Графы - это всего лишь узлы и связи между ними. Они не так часто используются в "обычном" программировании, как логические утверждения, но тоже имеют место быть. Графы имеют несколько видов, для них существует целый класс алгоритмов, позволяющий найти какие-то оптимальные значения связей между узлами, упорядочить их и всякое такое прочее - о них мы тут говорить не будем. А вот о логических утверждениях стоит поговорить более развернуто.

1.1. Логика - раздел математики.

Про логику в научных журналах одним из первых начал писать еще Аристотель, а все программирование, по большому счету, - это присваивание и ветвление. Вот как раз логику программисту знать необходимо.

Итак, просто вспомнить заради приведу тут основные логические операторы и законы:

И - логическое умножение. Приоритет высокий.

ИЛИ - логическое сложение. Приоритет низкий.

НЕ - отрицание. Приоритет высочайший.

В выражении "А = Б И Ц ИЛИ Д И НЕ Ж" сначала будет вычислено "НЕ Ж", за ним все "И", и уже после, в самом конце, будет вычислено "ИЛИ".

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

Законы логики.

1. Никакое высказывание не может быть истинным и ложным одновременно.

Тут все просто: выражение "Х = 1 И Х <> 1" всегда ложно.

2. Любое высказывание или истинно, или ложно - третьего не дано.

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

3. Утверждение истинно, а контрутверждение ложно.

Тут тоже все достаточно просто: "(А = Б) = НЕ (А <> Б)". 

4. Силлогизм.

Классика: "Всякий человек смертен. Сократ - человек, следовательно он смертен". Примитивный пример может быть таким: "(А = Б И Б = Ц) = (А = Ц)".

Исходя из этих законов существуют преобразования логических выражений (не забываем про приоритеты):

НЕ (А ИЛИ Б) = НЕ А И НЕ Б

НЕ (А И Б) = НЕ А ИЛИ НЕ Б

А И (Б ИЛИ Ц) = А И Б ИЛИ А И Ц

А ИЛИ Б И Ц = (А ИЛИ Б) И (А ИЛИ Ц) 

А ИЛИ А И Б = А

А И (А ИЛИ Б) = А

Интереса заради можно разобрать такое вот выражение, приведенное в этой вот публикации.

((ПН И ПНП) И (РН И РНП)) ИЛИ (( ПН = Ложь ) И (РН И РНП)) ИЛИ ((ПН И ПНП) И (РН = Ложь))

Преобразуем это выражение, убрав константы:

(А И Б) И (Ц И Д) ИЛИ НЕ Ц И (А И Б) ИЛИ НЕ А И (Ц И Д)

Тут условие будет истинным в следующих случаях: 1. А = Б = Ц = Д = ИСТИНА. 2. А или Ц = ЛОЖЬ, Б = Д = ИСТИНА. При том А может быть ЛОЖЬ только тогда, когда Ц = Д = ИСТИНА, а Ц может быть ЛОЖЬ только когда А = Б = ИСТИНА.

Отсюда можно сделать вывод, что если А И Б = ИСТИНА, то нас не интересует Ц И Д, и, соответственно, наоборот. Отсюда прямо следует, что данное условие эквивалентно следующему:

(А ИЛИ Ц) И (А И Б ИЛИ Ц И Д)

Какая логика преобразований тут использовалась? Из первоначального условия ясно, что (А И Б) И (Ц И Д) - это основное условие, при этом если А ИЛИ Ц неистинны, то для А становится бессмысленно Б, а для Ц - Д. В итоге у нас должно быть истинным одно из А или Ц. Так и запишем: А ИЛИ Ц. А дальше уже мы можем А И Б логически сложить с Ц И Д, т.к. у нас или А, или Ц истинно. При ложности А будет проверяться только истинность Ц и Д, а для ложности Ц - только А и Б. Если А и Ц ложны, то и само условие тоже будет ложно.

2. Принципы древних.

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

2.1. Не стоит плодить сущности без необходимости

Данный принцип сформулировал Уильям Оккам, живший в XIII-XIV веках. Суть его в том, что если что-то можно объяснить без привлечения дополнительных сущностей, то привлекать эти сущности не нужно. Истоки же редуцирования (т.е. минимизации и упрощения) в логике сокрыты во глубине веков, а бритву и Оккама первым, если мне не изменяет память, скрестил Лейбниц (в действительности он не Оккама с ней скрестил, а номинализм, "протагонистом" которого был Оккам).

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

При этом нужно понимать, что качели эффективности программного кода могут прямо зависеть от количества сущностей. И минимальное их количество может быть неэффективным, Например, если попытаться снизить количество потребляемой памяти, то время разработки и зачастую производительность такого экономного по памяти решения будут обычно хуже, чем у решения, не особо ограничивающего использование памяти, например, для кеширования часто используемых значений. Также запрос в цикле, обрабатывающий по одному элементу данных, будет обычно хуже, чем обработка массовой выборки (если, конечно, вы не обрабатываете только один элемент).

Но в большинстве других случаев стоит разобраться, нужны ли нам те или иные переменные, функции, процедуры, модули, документы, регистры, справочники, ПВХ или иные какие объекты. Следует стараться использовать уже имеющееся, и если этого действительно не хватает для реализации задачи, плодить новую сущность, предварительно посоветовавшись с архитектором (скрам с его покером планирования тут однозначно рулит).

2.2 Лучшее - враг хорошего.

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

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

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

2.3. Все гениальное - просто.

Так Йозеф Геббельс перефразировал слова Леонардо да Винчи. И если выкинуть из объяснения чего-либо все лишнее, то получится как раз простое и достаточное этого чего-либо объяснение. Другими словами, это предельный вариант принципа Оккама.

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

2.4. Глаза боятся - руки делают.

В словаре народной фразеологии данное понятие отражено весьма полно:

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

Для разработчиков программного обеспечения данное выражение должно быть крайне полезно, т.к. сложность, с которой приходится работать, бывает весьма высока. Это как раз следствие того, что большинство программных продуктов (особенно на 1С) не представляют из себя образчиков гениальности - в них полно лишних сущностей, но это цена компромисса между работающим ПО и сферическим в вакууме ТЗ, которое никто и никогда не будет писать.

3. Мораль.

Исходя из вышесказанного могу подытожить следующим образом:

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

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

3. Не стоит тратить множество времени на идеальное ТЗ - оно все равно скорее всего не будет идеальным, но полностью отказываться от раздумий на тему того, как это сделать, тоже не стоит.

4. Не стоит усложнять задачу. Иногда, если отвлечься, приходит неплохое и достаточно простое решение.

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

70

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. gubanoff 46 23.01.19 15:30 Сейчас в теме
(0) Всегда рекомендую читать классику - "Совершенный код" С. Макконнелл. Там написано все и подробно.

Не хочется обижать авторов статей, но они освещают только малый процент того, что есть в "совершенном коде".
JohnConnor; YPermitin; kraynev-navi; ilialin; ivanov660; PLAstic; klinval; zqzq; CSiER; lunjio; wowik; Vladimir Litvinenko; starik-2005; +13 Ответить
2. starik-2005 1920 23.01.19 15:39 Сейчас в теме
(1) так я, например, постоянно предлагаю Макконнелла читать всем и каждому. Моя статья тут совершенно о другом - о том, что нужно знать программисту, чтобы вообще иметь возможность писать программы. Ну и о том, что совершенного кода написано не так много, что лучше написать не такой совершенный, но работающий код, чем не написать никакого кода )))
mvxyz; Dem1urg; +2 Ответить
23. zqzq 16 25.01.19 09:24 Сейчас в теме
(2) Кстати, по поводу Совершенного кода, в оригинале название книги "Code Complete", совсем другой нюанс смысла.
34. kote 499 27.02.19 19:17 Сейчас в теме
(23) не-а, как раз перевод "совершенный" тут самое то - "совершенный" оно от "свершился -> завершился"..
Завершенный, законченный, самодостаточный - как раз это значение у "complete".. а просто перевод "завершенный" - лишен смысла, который в самой книге.
38. Crazy_Max 52 26.04.19 13:30 Сейчас в теме
(34)
не-а, как раз перевод "совершенный" тут самое то - "совершенный" оно от "свершился -> завершился"...

(34)
Тогда нужно акцентировать внимание на букве "Ё" в слове "совершённый". А вообще, я бы перевёл название во что-то вроде "Конечный код". В любом случае название "Совершенный код" несёт практически противоположный смысл, чем тот, который вкладывал Макконнелл.
40. starik-2005 1920 26.04.19 14:51 Сейчас в теме
(38)
я бы перевёл название во что-то вроде "Конечный код"
"Конченный код" ))) Типа писал его совсем конченный программер )))
41. Crazy_Max 52 26.04.19 19:41 Сейчас в теме
Ну уж кто чего видит...
3. pm74 127 23.01.19 16:10 Сейчас в теме

Отсюда прямо следует, что данное условие эквивалентно следующему:
(А ИЛИ Ц) И (А И Б ИЛИ Ц И Д)


ну неправильно же , исправьтесь

(А И Б) И (Ц И Д) ИЛИ НЕ Ц И (А И Б) ИЛИ НЕ А И (Ц И Д)

и

(А ИЛИ Ц) И (А И Б ИЛИ Ц И Д)

не эквивалентны
Алексей_mir2mb; +1 Ответить
4. starik-2005 1920 23.01.19 16:23 Сейчас в теме
(3) не эквивалентны в двух случаях из 16-ти. Может Вы предложите, как сократить это выражение?
Алексей_mir2mb; +1 Ответить
5. pm74 127 23.01.19 16:26 Сейчас в теме
(4) ну например
Ц И Д И (НЕ А ИЛИ Б) ИЛИ НЕ Ц И А И Б
или
(НЕ Ц ИЛИ Д) И (НЕ А ИЛИ Б) И (Ц И Д ИЛИ А И Б)

наверняка есть и получше варианты
Алексей_mir2mb; starik-2005; +2 Ответить
7. starik-2005 1920 23.01.19 16:41 Сейчас в теме
(5) как вариант! Полезно иногда понимать, что где-то ошибаешься.
8. pm74 127 23.01.19 16:46 Сейчас в теме
(7) может кто нибудь заморочится и напишет обработку на тему алгоритма Квайна-МакКлоски
9. starik-2005 1920 23.01.19 16:55 Сейчас в теме
(8) кстати, очень интересная тема. Постараюсь нарисовать ее в ближайшее время.
6. pm74 127 23.01.19 16:38 Сейчас в теме
Просто оставлю здесь
ВЫБРАТЬ
	ИСТИНА КАК БУЛЕВО
ПОМЕСТИТЬ ИСТИНАЛОЖЬ
ОБЪЕДИНИТЬ
ВЫБРАТЬ
	ЛОЖЬ
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ИСТИНАЛОЖЬ.БУЛЕВО КАК А,
	ИСТИНАЛОЖЬ2.БУЛЕВО КАК Б,
	ИСТИНАЛОЖЬ3.БУЛЕВО КАК Ц,
	ИСТИНАЛОЖЬ4.БУЛЕВО КАК Д
ПОМЕСТИТЬ СОЧЕТАНИЯ
ИЗ
	ИСТИНАЛОЖЬ КАК ИСТИНАЛОЖЬ,
	ИСТИНАЛОЖЬ КАК ИСТИНАЛОЖЬ2,
	ИСТИНАЛОЖЬ КАК ИСТИНАЛОЖЬ3,
	ИСТИНАЛОЖЬ КАК ИСТИНАЛОЖЬ4
;

////////////////////////////////////////////////////////////­//////////////////// 
ВЫБРАТЬ
А,Б,Ц,Д,
((А И Б) И (Ц И Д)) ИЛИ  (( А = Ложь ) И (Ц И Д)) ИЛИ ((А И Б) И (Ц = Ложь)) КАК Шаблон,
(А И Б) И (Ц И Д) ИЛИ НЕ Ц И (А И Б) ИЛИ НЕ А И (Ц И Д) КАК Выражение1,
(А ИЛИ Ц) И (А И Б ИЛИ Ц И Д) КАК Выражение2,
Ц И Д  И (НЕ А ИЛИ Б) ИЛИ НЕ Ц И А И Б  КАК Выражение3
ПОМЕСТИТЬ ПРОВЕРКА
ИЗ
	СОЧЕТАНИЯ КАК С
	;
ВЫБРАТЬ
А,Б,Ц,Д, 
Шаблон = Выражение1 Проверка1,
Шаблон = Выражение2 Проверка2,
Шаблон = Выражение3 Проверка3
Из   ПРОВЕРКА КАК П

Показать
Алексей_mir2mb; singlych; fancy; unichkin; acanta; +5 Ответить
10. Painted 28 24.01.19 10:00 Сейчас в теме
2.4.1. Слона надо есть по кусочкам.
Если задача пугает громоздкостью и/или сложностью, разбейте ее на более простые подзадачи. И разбивайте до тех пор, пока они не станут простыми и легко реализуемыми.
IgorS; Yimaida; Yakud3a; alex-l19041; starik-2005; +5 Ответить
11. FreeFin 2 24.01.19 12:32 Сейчас в теме
Frustra fit per plura quod potest fieri per pauciora
Но почему почти никто не задумывается, что достаточное не всегда правильное? Привычка, так принято и иначе нельзя? Всего лишь вопрос, а почему нельзя? Потому что "Оккам так сказал"?
Алексей_mir2mb; +1 Ответить
14. ADirks 181 24.01.19 14:13 Сейчас в теме
(11) потому что правильное не всегда правильно
brr; Алексей_mir2mb; +2 Ответить
16. starik-2005 1920 24.01.19 14:37 Сейчас в теме
(11) всегда есть смысл предметно поговорить об этом. Но для этого нужно какой-то пример разобрать. У Вас есть пример?
12. logarifm 1045 24.01.19 12:44 Сейчас в теме
2. Любое высказывание или истинно, или ложно - третьего не дано.


В терминах 1С еще Или НЕОПРЕДЕЛЕНо :)
jif; Алексей_mir2mb; sm.artem; +3 Ответить
13. qwinter 596 24.01.19 13:57 Сейчас в теме
(12) Только в случае если оно существует)))
15. starik-2005 1920 24.01.19 14:36 Сейчас в теме
(12)
В терминах 1С еще Или НЕОПРЕДЕЛЕНо :)
Результат логической операции не может быть неопределен. Или может? )))
19. ADirks 181 24.01.19 17:33 Сейчас в теме
(15) В Булевой алгебре не может, т.к. эта алгебра определена на множестве {Истина, Ложь}
А в SQL может, т.к. там множество {Истина, Ложь, Null}
Алексей_mir2mb; +1 Ответить
17. Jokemas 83 24.01.19 15:01 Сейчас в теме
Хорошая статья. Порадовало упоминание создателя "Соло на клавиатуре" =)).
18. capitan 1225 24.01.19 15:19 Сейчас в теме
У некоторых программистов бывает еще так:
rpgshnik; Bajo; kote; TABEZI1234; EVKash; Алексей_mir2mb; Yakud3a; starik-2005; +8 Ответить
31. TABEZI1234 25.01.19 22:33 Сейчас в теме
20. morin 13 24.01.19 19:54 Сейчас в теме
Спасибо автору за статью.
Процентов 80 работы программиста - это не написание кода, а его чтение (изучение чужого кода, отладка, изучение документации). У программистов 1С эта доля может доходить до 98 процентов.
Может кто-нибудь поделится, как читать код (опыт, методики, инструменты)?
Но, думаю, это тема для отдельной статьи.
ilialin; acanta; starik-2005; Алексей Воробьев; Алексей_mir2mb; +5 Ответить
26. starik-2005 1920 25.01.19 10:40 Сейчас в теме
(20)
Но, думаю, это тема для ...
Кстати, хорошая идея. Попробую изложить свое видение данной проблемы в эти выходные.
kote; json; +2 Ответить
27. genayo 25.01.19 10:53 Сейчас в теме
(26) Обязательно пишите, вроде неплохо получается :)
21. Артано 654 25.01.19 04:14 Сейчас в теме
Спасибо за внесенную лепту. А также, за своеобразный пинок меня, чтобы я продолжил публикации ))
22. 1c-intelligence 8246 25.01.19 07:23 Сейчас в теме
24. awk 689 25.01.19 10:02 Сейчас в теме
Про логику порадовало

С. Н. Виноградов, А. Ф. Кузьмин
Логика
УЧЕБНИК ДЛЯ СРЕДНЕЙ ШКОЛЫ СССР
*** 1954 ***

https://sheba.spb.ru/shkola/logika-vinograd1954.htm

очень рекомендую....

Я правда читал для вузов, вышеприведенный попроще...
starik-2005; +1 Ответить
28. Painted 28 25.01.19 16:03 Сейчас в теме
(24)
УЧЕБНИК ДЛЯ СРЕДНЕЙ ШКОЛЫ СССР
*** 1954 ***
Сорри, немного оффтопа. О вечном.
Недавно с удивлением узнал, что мой ребенок учит дифференциалы по Фихтенгольцу. По которому в свое время учился я и, секундочку, моя мама. ))
29. awk 689 25.01.19 17:24 Сейчас в теме
(28)
Фихтенгольцу


Тут оказалось, что учебники 40-50 гораздо более понятны и адекватнее современных. Энтузиасты взялись за переиздание. Кто использует говорят эффект потрясающий, школьники которые считались в школе безнадежно тупыми - выбиваются в уверенные хорошисты (но это по слухам - не проверял сам).
39. Crazy_Max 52 26.04.19 13:47 Сейчас в теме
(28)
дифференциалы по Фихтенгольцу

Это не тот Фихтенгольц, который еще и по программированию учебники писал? Я, будучи школьником, изучал по нему Паскаль в 10-м классе, а в 11-й класс пошел в другую школу. Там препод посмотрел на книжку, по которой я учился, затем указал мне на лучший компьютер в классе и попросил, чтобы я не мешал ему на уроках.
А книжка, и в правду, давалась с кровью и седыми волосами. Только позже, когда мне попались в руки другие книги по программированию, я в сравнении осознал, насколько это было жестоко по отношению к моей невинной детской головушке...
25. rwn_driver 8 25.01.19 10:34 Сейчас в теме
Можно ещё почитать занимательную логику или Рэймонд М. Смаллиан "Как же называется эта книга?".
30. vasilev2015 1366 25.01.19 21:45 Сейчас в теме
Хочу поблагодарить Сергея за поддержку статьи про логику и математику
32. TABEZI1234 25.01.19 22:33 Сейчас в теме
не понял, это сарказм был в статье?
33. TABEZI1234 25.01.19 22:34 Сейчас в теме
Процентов 80 работы программиста - это не написание кода, а его чтение (изучение чужого кода, отладка, изучение документации). У программистов 1С эта доля может доходить до 98 процентов.
Может кто-нибудь поделится, как читать код (опыт, методики, инструменты)?
Но, думаю, это тема для отдельной статьи. ---Согласен
Crazy_Max; kote; +2 Ответить
35. 3vs 23.04.19 11:18 Сейчас в теме
"2. Любое высказывание или истинно, или ложно - третьего не дано."
А как же Троичная логика?
ru.wikipedia.org/wiki/Троичная_логика

Перечень значений нечёткой трёхзначной логики с двумя чёткими и с одним нечётким значением помимо «истинно» и «ложно» включает также третье значение, которое нечётко и трактуется как «не определено» или «неизвестно», или, в простонародье, х.з.

Примерами значений нечёткой трёхзначной логики с одним чётким и с двумя нечёткими значениями являются: («меньше», «равно», «больше»), («уклон влево», «прямо», «уклон вправо») и другие.

Примерами значений нечёткой трёхзначной логики с тремя нечёткими значениями, к которым сводится очень большое количество практических народнохозяйственных задач, являются: («меньше», «равно, в допустимых пределах», «больше»), («уклон влево», «прямо, в допустимых пределах», «уклон вправо»), («холодно», «прохладно», «жарко») и другие.
37. Perfolenta 162 23.04.19 21:26 Сейчас в теме
(36) да, были люди в наше время... богатыри, не мы...
42. Rustig 1172 07.08.19 10:40 Сейчас в теме
пусть идет учиться не на очередной сертификат, а на курс логики.

для улучшения собственных навыков программирования идеально подходит парное программирование с более опытным наставником

понравилась мысль про "глаза боятся - руки делают". спасибо!
43. starik-2005 1920 07.08.19 22:26 Сейчас в теме
(42) этим мыслям тысячи лет)))
Оставьте свое сообщение