Я понял, откуда берётся говнокод.
От: dimgel Россия https://github.com/dimgel
Дата: 17.08.14 02:25
Оценка: 20 (2) +1
Иногда меня обвиняют в овердизайне. На вскидку вспоминается два случая. Один из которых — заслуженный (но через этот опыт надо было пройти), а со вторым обвинением я не согласен. Обвинение это было выдано говно-программистом, тем самым Васей, который наклепал тяп-ляп проект, начал стричь бабло и набрал людей, чтобы они переписали ага, как же, переписали... Щас. Чтобы они продолжали гнать функционал поверх рассыпающегося говна, но это другая история.

А нынешняя история следующая: я тут пилю вещи, превышающие мою квалификацию (логика сложноразмазана между compiletime (макросы) для статически оптимизируемых случаев и runtime (генерируемый макросами код) для динамических неоптимизируемых, а dragon book так и не дочитал, поэтому всё на костылях). И обнаруживаю, что пишу как раз в стиле того говно-программиста — без паттернов, которых не знаю, без нормальной структуры — грубая копипаста в стиле "как слышится, так и пишется".

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

А ещё вспоминается метода Кента Бека (описана кажется в TDD): 10 пишем лишь бы работало; 20 удаляем задвоения кода; goto 10. Только вот в данном случае на входе шага 20 будет строк эдак 5-10 тысяч, зубодробительных костылей. Как там я буду задвоения искать и удалять/заворачивать в паттерны — одному богу известно.
Отредактировано 17.08.2014 5:35 dimgel . Предыдущая версия .
Re: Я понял, откуда берётся говнокод.
От: watchyourinfo Аргентина  
Дата: 17.08.14 03:47
Оценка: +3
D>А ещё вспоминается метода Кента Бека (описана кажется в TDD): 10 пишем лишь бы работало; 20 удаляем задвоения кода; goto 10. Только вот в данном случае на входе шага 20 будет строк эдак 5-10 тысяч, зубодробительных костылей. Как там я буду задвоения искать и удалять/заворачивать в паттерны — одному богу известно.

немного офф: не так уж редко встречаются ситуации, когда удаление повторений делает код хуже (потому что вводится лишняя сущность, и если она недостаточно generic, то она просто добавляет шум).
Re: Я понял, откуда берётся говнокод.
От: мыщъх США http://nezumi-lab.org
Дата: 17.08.14 04:32
Оценка: +2
Здравствуйте, dimgel, Вы писали:

D>Иногда меня обвиняют в овердизайне.

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

это даже хуже, чем говнокод. потому что никакой его фрагмент не работает без кода всего проекта. следовательно, повторное использование кода возможно только на уровне АПИ высшего уровня. а где-то там внутри есть такой клевый компилятор регулярных выражений в nfa, вот только его проще переписать заново чем тянуть за собой в другой проект кучу мусора.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: Я понял, откуда берётся говнокод.
От: dimgel Россия https://github.com/dimgel
Дата: 17.08.14 04:38
Оценка: +2 -2
Здравствуйте, мыщъх, Вы писали:

D>>Иногда меня обвиняют в овердизайне.

М>а может правильно обвиняют?

Ну тебе виднее, разумеется.

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


Овердизайн выглядит несколько по-другому, а описанная тобой проблема — слишком сильная связность — это как раз следствие отсутствия дизайна как такового.
Re: Я понял, откуда берётся говнокод.
От: andyag  
Дата: 17.08.14 05:10
Оценка: +1
Здравствуйте, dimgel, Вы писали:

D>А нынешняя история следующая: я тут пилю вещи, превышающие мою квалификацию (логика сложноразмазана между compiletime (макросы) для статически оптимизируемых случаев и runtime (генерируемый макросами код) для динамических неоптимизируемых, а dragon book так и не дочитал, поэтому всё на костылях). И обнаруживаю, что пишу как раз в стиле того говно-программиста — без паттернов, которых не знаю, без нормальной структуры — грубая копипаста в стиле "как слышится, так и пишется".


D>Вывод: говнокод начинается, когда пытаешься проглотить слишком большой кусок ненатренированной глоткой.


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

1. Понимание задачи (чтение, коммуникации, анализ, "постановка для себя", риски, гуглинг)
2. Выдумывание решения (понимание "достаточно хорошего решения", риски, самокритика, эксперименты, поиск готовых решений, гуглинг, релевантный опыт)
3. Решение задачи (написание кода, самокритика, рефакторинг, тестирование, релевантный опыт)

Всякие джуниоры-сеньоры отличаются как раз по общему количеству доступного им ресурса и по желанию/возможности/способности разделить этот ресурс между вышеописанными пунктами. В качестве примера возьмём задачку, которая требует 5/5/10.

Если мы джуниор с общим ресурсом 7, то раскидаем ресурс например вот так:
1. Понимание — 1/5 (прочитали тикет)
2. Выдумывание решения — 1/5 (прикинули в уме)
3. Решение — 5/10 (написали какой-то код)

Если мы сеньор с общим ресурсом 100, то "ожидается", что мы сможем обеспечить все эти самые 5/5/10 с хорошим запасом (скучная задачка).

Но вот если задачка требует ресурс 200, то сеньор с общим ресурсом 100 такую задачку уже не потянет.
Re[3]: Я понял, откуда берётся говнокод.
От: мыщъх США http://nezumi-lab.org
Дата: 17.08.14 05:22
Оценка: +1
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, мыщъх, Вы писали:


D>>>Иногда меня обвиняют в овердизайне.

М>>а может правильно обвиняют?
D>Ну тебе виднее, разумеется.
я же спрашиваю, а не утверждаю. динамическим программированием я и сам увлекаюсь. а книга дракона это далеко не самое лучшее чтиво. я бы Modern Compiler Implementation in C рекомендовал.


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

D>Овердизайн выглядит несколько по-другому, а описанная тобой проблема — слишком сильная связность — это как раз следствие отсутствия дизайна как такового.
это как раз пример налучшего дизайна. вот только лучший враг хорошего. библиотека динамической памяти использует же списки, очереди, поиск и прочие структуры данных и алгоритмы? а библиотека поиска динамическую память использует? использует!

что плохого в том, что модуль А использует модуль Б, а модуль Б использует модуль А? это как раз красиво, структурно и архитектурно. а вот кк тащить в свой проект эту красоту -- это да.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: Я понял, откуда берётся говнокод.
От: Abyx Россия  
Дата: 17.08.14 09:37
Оценка: -1
Здравствуйте, мыщъх, Вы писали:

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

М>это даже хуже, чем говнокод. потому что никакой его фрагмент не работает без кода всего проекта. следовательно, повторное использование кода возможно только на уровне АПИ высшего уровня. а где-то там внутри есть такой клевый компилятор регулярных выражений в nfa, вот только его проще переписать заново чем тянуть за собой в другой проект кучу мусора.
это не овердизайн, а недостаток дизайна.
при нормальном дизайне все части были бы завернуты в абстрактные интерфейсы, и любая часть легко заменялась бы (в тех же тестах)
In Zen We Trust
Re: Я понял, откуда берётся говнокод.
От: kleng  
Дата: 17.08.14 10:01
Оценка:
Здравствуйте, dimgel, Вы писали:

D>логика сложноразмазана


Вот это уже очень подозрительно. Попахивает кое-чем.

D>dragon book так и не дочитал, поэтому всё на костылях).


Никакая книга не решит твои проблемы магически. Особенно распиаренный dragon book.
Re[3]: Я понял, откуда берётся говнокод.
От: kleng  
Дата: 17.08.14 10:34
Оценка: -3
Здравствуйте, Abyx, Вы писали:

A>при нормальном дизайне все части были бы завернуты в абстрактные интерфейсы, и любая часть легко заменялась бы (в тех же тестах)


Легко заменялась, написав десяток классов-оберток. И дико бы тормозило.
Re[4]: Я понял, откуда берётся говнокод.
От: Abyx Россия  
Дата: 17.08.14 10:43
Оценка: -1 :))
Здравствуйте, kleng, Вы писали:

K>Здравствуйте, Abyx, Вы писали:


A>>при нормальном дизайне все части были бы завернуты в абстрактные интерфейсы, и любая часть легко заменялась бы (в тех же тестах)


K>Легко заменялась, написав десяток классов-оберток. И дико бы тормозило.


да, я всегда замечал что как только применю статический полиморфизм — всё сразу начинает тормозить
In Zen We Trust
Re: Я понял, откуда берётся говнокод.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.08.14 15:09
Оценка: +1
Здравствуйте, dimgel, Вы писали:

D>Иногда меня обвиняют в овердизайне. На вскидку вспоминается два случая. Один из которых — заслуженный (но через этот опыт надо было пройти), а со вторым обвинением я не согласен. Обвинение это было выдано говно-программистом, тем самым Васей, который наклепал тяп-ляп проект, начал стричь бабло и набрал людей, чтобы они переписали ага, как же, переписали... Щас. Чтобы они продолжали гнать функционал поверх рассыпающегося говна, но это другая история.


D>А нынешняя история следующая: я тут пилю вещи, превышающие мою квалификацию (логика сложноразмазана между compiletime (макросы) для статически оптимизируемых случаев и runtime (генерируемый макросами код) для динамических неоптимизируемых, а dragon book так и не дочитал, поэтому всё на костылях). И обнаруживаю, что пишу как раз в стиле того говно-программиста — без паттернов, которых не знаю, без нормальной структуры — грубая копипаста в стиле "как слышится, так и пишется".


D>Вывод: говнокод начинается, когда пытаешься проглотить слишком большой кусок ненатренированной глоткой.



Неверно. Говнокод может быть в случаях когда квалификация программиста превышает требования задачи.
Скорее у тебя проблема с адекватной декомпозицией задачи. Кстати неверная декомпозиция — частая (возможно основная) причина говнокода.


D>А ещё вспоминается метода Кента Бека (описана кажется в TDD): 10 пишем лишь бы работало; 20 удаляем задвоения кода; goto 10. Только вот в данном случае на входе шага 20 будет строк эдак 5-10 тысяч, зубодробительных костылей. Как там я буду задвоения искать и удалять/заворачивать в паттерны — одному богу известно.


Бек пишет про отдельные фукнции, а не огромную систему. См выше про декомпозицию.

ЗЫ. Когда пытался писать нечто вроде компилятора, то сам столкнулся с ситуацией когда я не мог понять как надо декомпозировать задачу, чтобы успешно её решить.
Re[2]: Я понял, откуда берётся говнокод.
От: dimgel Россия https://github.com/dimgel
Дата: 17.08.14 16:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>ЗЫ. Когда пытался писать нечто вроде компилятора, то сам столкнулся с ситуацией когда я не мог понять как надо декомпозировать задачу, чтобы успешно её решить.


Похоже на то, если к проблемам декомпозиции относится смутное понимание, что здесь надо бы таблицу символов забабахать и собственное AST, но AST параллельное уже имеющемуся скаловскому — категорически лень, а как с этой самой таблицей символов работать, а главное, про технику оптимизаций — я полное ХЗ.
Re[3]: Я понял, откуда берётся говнокод.
От: мыщъх США http://nezumi-lab.org
Дата: 18.08.14 01:54
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, мыщъх, Вы писали:



A>это не овердизайн, а недостаток дизайна.

A>при нормальном дизайне все части были бы завернуты в абстрактные интерфейсы, и любая часть легко заменялась бы (в тех же тестах)
к сожалению, этот "недостаток дизайна" на каждом шагу. как раз все части и завернуты в абстрактные интерфейсы. в результате чего библиотека поиска подстроки в строке работает с абстрактными строками. если бы строки были _действительно_ абстрактными (абстрактный "символ" вместо конкретного байта, где один и тот же символ может быть закодирован и одним, и двумя, и тремя, и четырьмя байтами, но функция сравнения символов это берет на себя). так ведь нет! слой абстракции от бинарного представления строки на самом деле является функциями-пустышками, тупо считывающими один или два байта и так же тупо их сравнивающих побитовым сравнением. и это как бы понятно, потому что быстро сравнить два символа в общем случае невозможно и придется либо держать в памяти огромные таблицы всех кодировок, либо требовать нормализации данных перед сранением). вот и возникает вопрос: зачем во многих проектах (CalmAV, SpiderMonkey) городить лишние сущности, если они не дают никакого профита?

еще одно наблюдения. в не-говнокоде как правило в одном файле реализована одна функция. профит? существенно меньший оверхид при линковке. если у нас есть своя библиотека и в ней 300 апи функций, но модуль foo использует только 10 из них, то линкеру, очевидно, требуется помощь. чтобы включать в проект только то, что реально используется.

а вот в говнокоде все это компилируется только одним большим куском говна. с другой стороны, до появления ссд дисков подход "один файл — одна функция" существенно замедлял компиляцию, по крайней мере нтфс очень плохо справляется с каталогами с кучей файлов
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: Я понял, откуда берётся говнокод.
От: uncommon Ниоткуда  
Дата: 18.08.14 02:47
Оценка: 2 (1)
Здравствуйте, мыщъх, Вы писали:

М>а просто выдрать часть кода из чужого проекта и скомпилировать в независимую утилиту, натыкаюсь на этот самый овер-дизайн


Да, даже ещё проще. Вот недавно надо было тривиальное изменение сделать в каком-то коде. Одна строчка кода. Ну и думаю, сейчас я быстренько юнит-тест для него накатаю. Делов-то: создать один объект и позвать у него один метод. Но не тут-то было! Это объект просто так не создашь. Для него надо фабрику, которую фиг знает где взять, а для фабрики нужны ещё и параметры, которые тоже объекты и которые тоже надо как-то сделать (через другие фабрики, duh!). И в довесок еще и аттрибуты для этих объектов правильно инициализировать. И это даже не джава. Клинический случай. Надо всё нафиг выбрасывать и заново делать.
Re[4]: Я понял, откуда берётся говнокод.
От: dimgel Россия https://github.com/dimgel
Дата: 18.08.14 02:52
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>один файл — одна функция


Поубивал бы.

Когда архитектуру затачивают не под задачу, а чтобы телогреечке было тепло
Автор: dimgel
Дата: 07.03.13
компилятор с линкером побыстрее работали, знаешь что получается? Ага, он самый.
Отредактировано 29.10.2014 2:32 VladD2 . Предыдущая версия .
Re[4]: Я понял, откуда берётся говнокод.
От: kleng  
Дата: 18.08.14 03:38
Оценка: +2
Здравствуйте, мыщъх, Вы писали:

М>еще одно наблюдения. в не-говнокоде как правило в одном файле реализована одна функция. профит? существенно меньший оверхид при линковке.


Разработчики SQLite — говнок темные люди и не слышали о таких вещах, поэтому распространяют исходный код в виде одного большого файла. Который (вероятно из-за их неграмотности), компилируется на порядок быстрее, чем тот же код, разбитый на множество файлов.
Re[5]: Я понял, откуда берётся говнокод.
От: мыщъх США http://nezumi-lab.org
Дата: 18.08.14 05:56
Оценка:
Здравствуйте, kleng, Вы писали:

K>Здравствуйте, мыщъх, Вы писали:


М>>еще одно наблюдения. в не-говнокоде как правило в одном файле реализована одна функция. профит? существенно меньший оверхид при линковке.


K>Разработчики SQLite — говнок темные люди и не слышали о таких вещах, поэтому распространяют исходный код в виде одного большого файла. Который (вероятно из-за их неграмотности), компилируется на порядок быстрее, чем тот же код, разбитый на множество файлов.


см. выделенное. а на счет того, что один большой файл компилируется быстрее чем один маленький -- просите, не верю. вы в курсе, что make не перекомпилирует файлы, в которых нет изменений? если у нас много файлов, то правка одного из них не затронет остальные (если только нет зависимостей), значит, исправить-и-пересобрать в случае большого файла сильно медленнее.

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

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

кстати, девелоперски репы очень часто _сильно_ отличаются от сорцов для хомячков, которым достаточно их собрать.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[4]: Я понял, откуда берётся говнокод.
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 18.08.14 06:52
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>еще одно наблюдения. в не-говнокоде как правило в одном файле реализована одна функция. профит? существенно меньший оверхид при линковке. если у нас есть своя библиотека и в ней 300 апи функций, но модуль foo использует только 10 из них, то линкеру, очевидно, требуется помощь. чтобы включать в проект только то, что реально используется.


Интересно, а есть примеры проектов с такой организацией?
По-моему опыту, удобней случаи с функциями, организованными в файлах по общей тематике. Например, математические функции в одном файле, работа со строками — в другом, скажем, поиск и работа с контурами — в третьем.
В чём удобство такой организации?
Во-первых, можно быстро, без документации узнать что есть в библиотеке, найти функцию, о которой даже и не думал. Например, вряд ли кто-то будет искать функцию clamp, sign или lerp — проще написать самому, порождая лишний мусор в исходниках. А так: заглянул, увидел, применил.
Во-вторых, меньше инклудов писать руками. С кучей файлов рано или поздно заколебаешься писать инклуд на каждую функцию и сделаешь самописную свалку инклудов, которая убьёт все преимущества такой мелкомодульности (хорошо ещё если в виде прекомпилированного заголовка).
И, в-третьих, уже лично для меня: не надо запоминать кучу сущностей. Помнить про один файл легче, чем про 10 или 20.
Re[6]: Я понял, откуда берётся говнокод.
От: kleng  
Дата: 18.08.14 07:08
Оценка:
Здравствуйте, мыщъх, Вы писали:

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


С вопросами веры — в церковь, а у нормальных людей принято делать эксперименты.

М>вы в курсе, что make не перекомпилирует файлы, в которых нет изменений?


В курсе. Но каждый добавочный файл — это нехилые накладные расходы, даже если он не компилируется, а только линкуется.
Re[4]: Я понял, откуда берётся говнокод.
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.08.14 07:12
Оценка: 5 (1)
Здравствуйте, мыщъх, Вы писали:
М>я же спрашиваю, а не утверждаю. динамическим программированием я и сам увлекаюсь. а книга дракона это далеко не самое лучшее чтиво. я бы Modern Compiler Implementation in C рекомендовал.
Да, Аппель — рулит.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.