• EFORTH для программируемого калькулятора
    0
    Что заказчик захотел, то и получил при совпадении с интересами производителя
  • EFORTH для программируемого калькулятора
    0
    У МК-161 есть разъём, который относительно легко кодировать
  • EFORTH для программируемого калькулятора
    0
    Калькуляторы — это побочная продукция предприятия. Используются как программируемые контроллеры для приборов их же производства, востребованные одним заказчиком (или некоторыми).
  • ФНС потратит 3,3 млрд руб, чтобы приспособить свою систему к отечественному «Линуксу» и «Офису»
    0
    Как известно, в рамках программы импортозамещения государственные ведомства обязаны заменять дорогие американские Windows и MS Office дешёвыми российскими аналогами
    Откуда известно именно о таком акценте перехода?
  • Релиз PVS-Studio 6.26
    0
    Я не путаю. В компиляторе нет неопределённых мест по природе программ на цифровых вычислительных устройствах(с поправкой на точность определения машинного языка). Неопределённость может быть только в спецификации. Вопрос лишь в том, как именно определяется поведение в компиляторе — наиболее разумным способом или абы как ради баллов в очках оптимизации, задано один раз или меняется от версии к версии. Unspecified же поведение как раз-таки определено на уровне стандарта, но подразумевает возможность выбора. В этом и суть названия, которое плохо передаётся на русском, — оно определено, но не специфицировано.
  • Релиз PVS-Studio 6.26
    –2
    Компилятор видит, что в переменной r считается некоторая сумма. Переполнения переменной r произойти не должно. Иначе это неопределённое поведение, которое компилятор никак не должен рассматривать и учитывать.
    Это, к сожалению, распространённое заблуждение, в которое, увы, верят и разработчики трансляторов. Поведение, не определённое в стандарте означает, что ответственность за его определение переносится с создателей стандарта на создателей транслятора. Это совсем не означает, что оно не должно учитываться, но именно так многие считают и распоряжаются своей отвественностью так, как Вы описали.
    Претензия к компилятору вполне обоснована, но расчёт на то, что тут кто-то кому-то должен был бы наивен.
    Тем не менее, прочувствовать правильный учёт ошибочной ситуации можно, включив опции -fsanitize=undefined -fsanitize-undefined-trap-on-error.
  • Обнаружение уязвимостей в теории и на практике, или почему не существует идеального статического анализатора
    +3
    Наверно потому, что это ортогональные вещи. Опечатки могут приводить к ошибкам проверки, но злоумышленников интересует именно ошибки проверки вне зависимости от причины их происхождения, а не опечатки как таковые.
  • Команда PVS-Studio непредвзята при написании статей
    0
    Воспроизводилось что? Во время отдыха я прочитал новость, посмотрел код, нашёл неточность, вырвал кусок, собрал, увидел результат, описал его под новостью. Собирать и тестировать NGINX и даже официально уведомлять об ошибке никогда не входило в мои планы.
    Тут Andrey2008 постоянно борется с таким пренебрежительным отношением к ошибкам, но оно, очевидно, неискоренимо даже в среде ценителей.
  • Команда PVS-Studio непредвзята при написании статей
    0
    Из чего Вы сделали вывод, что его не было в исполнимом коде?
  • Команда PVS-Studio непредвзята при написании статей
    0
    Это практическая ошибка, проявляющаяся на gcc. И показатель качества — это только качество кода, а не реакция на уведомления. Реакция — это, всё же, о другом
  • Команда PVS-Studio непредвзята при написании статей
    0
    Вы проигнорировали моё упоминание бесконечной истории. Я не искал специально ошибки в NGINX, а просто потянул ниточку новости — и понеслось. Ошибки в NGINX не досадная случайность, а закономерность, вызванная подходом к написанию кода. Это именно некачественный код рыхлых, переутяжелённых функций.
  • Команда PVS-Studio непредвзята при написании статей
    +1
    Вывод: где мы нашли меньше ошибок при написании статьи, там и код лучше :). Всё честно.
    Давайте как пример рассмотрим NGINX, который Вы привели как пример качественного проекта, свидетельством чему было невыявление ошибок стат. анализом в 2014.
    В 2017 вышла новость об устранении в нём уязвимости.
    Я обратил внимание на то, как уязвимость была устранена:
    +            if (size > NGX_MAX_OFF_T_VALUE - (end - start)) {
    +                return NGX_HTTP_RANGE_NOT_SATISFIABLE;
    +            }
    +
                 size += end - start;

    Это было устранение возможного переполнения. Я решил проверить как выводятся start и end, ведь переполнения во время арифметических действий для проверки возможности переполнения других арифметических действий для меня не являются новостью.
    Я увидел следующую картину:
    while (*p >= '0' && *p <= '9') { 
       if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) { 
            return NGX_HTTP_RANGE_NOT_SATISFIABLE; 
       } 
       start = start * 10 + *p++ - '0'; 
    }

    Проверка с выходом из функции должна была предотвращать возможное переполнение целого со знаком start, но вместо такого сложения
     start = start * 10 + (*p++ - '0'); 
    было сделано такое
     start = (start * 10 + *p++) - '0'; 
    Что приводит к возможности переполнения левой части, а учитывая знаковость start, это является неопределённым поведением, что не даёт гарантию компенсации последующим вычитанием '0'. Тогда я даже смог добиться некорректного поведения при компиляции похожего куска кода с помощью gcc с оптимизацией.
    Это всё ставило под удар конечное утверждение об исправлении уязвимости, так как эта цепочка при определённых обстоятельствах могла привести к некорректности проверки.

    Я сообщил о своей находке и через некоторое проблема была исправлена. Это было отрадно, но сама заплатка снова дала повод задуматься. Подобный функционал был разбросан по множеству перегруженных кодом функций. Эти куски не могли быть обобщены в одну функцию, которая могла быть подвергнута тщательному осмотру и тестированию из-за обилия неструктурного кода, мешающего провести декомпозицию. При таком подходе к написанию кода остаётся только гадать, сколько похожего кода было не затронуто исправлением, так как его трудней выявить. Более того, я обнаружил ещё недостатки, но уже утратил желание в этом участвовать — это стало походить на бесконечную историю.
    А теперь вопросы:
    1. Способен ли подобные ошибки находить анализатор?
    2. Насколько качественный код NGINX?
    3. Насколько верно утверждение про связь невыявления ошибок стат.анализом и качеством?
  • Команда PVS-Studio непредвзята при написании статей
    –1
    Вы, действительно, предвзяты в статьях. Вот пример:
    Если проект качественный, то мы пишем, что не смогли найти ошибок
    Здесь содержится логическая ошибка. Вы предвзято связываете качество проекта с возможностью нахождения ошибок вашим инструментом, но это не так. Невозможность найти ошибки статическим анализатором слишком мало говорит о качестве и наоборот, что, естественно, не отменяет пользы от использования анализатора.
  • Английский язык: взгляд инженера
    +1
    Даже в технических (точных) науках докторские бывают так себе, что уж творится в гуманитарных науках.
    Такое пренебрежительное отношение сверху к «этим вот гуманитариям» постоянно встречается в среде программистов. Хотя с чего бы? Естественно возникшие языки и то, что с ними связано является несоизмеримо более сложной темой, чем языки программирования и то, что с ними связано.
  • Космический язык, ч. 1: универсальна ли универсальная грамматика?
    0
    там он подробно обьясняет про какую рекурсию идет речь
    То есть, рекурсия как таковая в языке есть и речь лишь об отсутствии некой рекурсии Хомского в трактовке Эверетта?
  • Космический язык, ч. 1: универсальна ли универсальная грамматика?
    0
    В этой статье, кстати, не говорится, что в языке Пираха нет рекурсии. Речь об особом типе рекурсии, которую автор статьи называет рекурсией Хомского, и, вообще, проходится по этому очень поверхностно. Поэтому утверждение
    идея универсальной грамматики была сильно подмочена, когда разобрали язык индейцев пираха, в котором нет рекурсии.
    как минимум не точно.
  • Космический язык, ч. 1: универсальна ли универсальная грамматика?
    0
    Рекурсия нужна для возможности выражения более сложных вещей, чем без неё. Это не опровергает универсальную грамматику также, как наличие подмножества не опровергает наличие полного множества — как регулярные выражения не опровергают контекстно свободные грамматики.
  • Яндекс.Станция: оффлайн-магазин, очередь на 300 человек и начало продаж
    0
    Неплохой домашний СОРМ получился
    После того, как все поголовно стали пользоваться мобильным СОРМ, не смешно.
  • Рефакторинг программы на Go: ускорение в 23 раза
    0
    Блокирующее I/O это то, которое возвращает управление только тогда, когда весь запрашиваемый блок данных был получен или уже не может быть получен.
  • Низкоуровневая оптимизация кода на платформе Эльбрус: векторное сложение uint16_t с помощью интринсиков
    0
    Интринсики, скорее, продолжение языка компилятора. Он обрабатывает их по особому, не как обычную библиотеку.
  • Рефакторинг программы на Go: ускорение в 23 раза
    0
    Надо уточнить, что речь про блокирующее I/O. На неблокирующем разницы не будет.
  • Вся правда об ОСРВ от Колина Уоллса. Статья #3. Задачи и планирование
    0
    Проблема в самих дробях. В крайнем случае придётся заниматься факторизацией длинных(>2^64) чисел, при этом потребность в памяти всё равно может расти из-за простых числителя и знаменателя. Итого — потенциальная бомба по памяти и вычислительной сложности в задачах настоящего времени. Это помимо того, что существуют иррациональные числа — действительные числа, непредставимые в виде простой дроби. Довольно безумно.
  • Психология читабельности кода
    0
    Не знаю, почему Вам показалось, что эти языки были приведены для доказательства рекомендаций, появившихся до C
    в том абзаце мы говорили про «структурный код» (1968). Си появился в 1969.
    1. C появился в 1972, не путайте с B
    2. Структурное программирование — это дисциплина, а не гайдлайн. Не удивительно что я Вас не понял.
    3. «В том абзаце» мы не могли говорить, что бы Вы не имели ввиду, это реплика отдельного человека. А что Вы имеете ввиду довольно сложно понять, и, соответственно, сложно понять, в чём Ваши претензии, хотя картина всё ясней.

    Теперь по части эффективности single return
    Вы так поспешили скопировать этот кусок, что не смогли понять:
    1. В MISRA C 1998 нет правила 14.7. Это относится к следующей надписи MISRA C 2004
    2. Если Вы всё-таки посмотрите список для MISRA C 1998, заметите что-то странное
    3. Шумные правила не означают, что они ухудшают качество кода, это всего лишь означает, что в конкретном исследовании положительная корреляцияоказалась невелика
    Из чего можно сделать вывод, что Вы не пытались понять, о чём говорится в исследовании и что это означает.

    Вы привели в качестве аргумента в споре “early return vs single return” новые языки, дизайн которых опирается на early return. Поздравляю, you played yourself.

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

    Это они чушь какую-то написали, не посоветовавшись с Вами?
    да.
    Это, как раз, означает, что Вы придумываете свои собственные понятия, и Ваше понимание единственного выхода противоречит общепринятому.
  • Психология читабельности кода
    0
    Загляните ещё в английскую Википедию
    The most common deviation, found in many languages, is the use of a return statement for early exit from a subroutine. This results in multiple exit points, instead of the single exit point required by structured programming.
    Это они чушь какую-то написали, не посоветовавшись с Вами?
  • Психология читабельности кода
    0
    Понятия «структурный поток выполнения» не существует так же, как и не существует понятия «неструктурный код» в контексте кода, использующего early return. Хватит придумывать новый термин каждый раз когда заканчивается аргументация.
    Структурный поток выполнения — это не новый термин, придуманный мной, а всего лишь сочетание слов, которые я использовал как синоним для кода, написанного в соответствии с принципами структурного программирования. Я вижу, это Вас смущает, но таковы особенности обычного человеческого языка — они позволяют достаточно вольно обращаться со словами. Я так понимаю, Вы сконцентрировались на принципе «один вход — один выход», поэтому упустили из виду, что он не исчерпывающий, отсюда и недопонимание.
    Для доказательства актуальности гайдлайнов, появившихся до си, пример крайне неудачный
    Не знаю, почему Вам показалось, что эти языки были приведены для доказательства рекомендаций, появившихся до C(особенно MISRA C, конечно), так как я сразу написал, что в них даже не ставили задачу сделать код структурным. В действительности, это было ответ на это:
    Значит ли, что стоит убирать исключения из всех яп их использующих? Нет.
    Вопрос был задан так, будто это совсем уже что-то безумное. А как видим, нет — исключение исключений стало банальным действом.
  • Психология читабельности кода
    0
    превосходный совет, рекомендую
    Но сами Вы им не воспользовались, потому что то, что Вы описали не имеет отношение к структурному потоку выполнения. Всё-таки, неплохо бы почитать про структурное программирование, хотя бы и на Википедии.
    Опять же, механизм исключений, появившийся позже, противоречит принципу sese. Значит ли, что стоит убирать исключения из всех яп их использующих? Нет.
    Из уже используемых языков ничего удалять нельзя, можно только добавлять — такова логика развития языка.

    В новых же языках исключения начали убирать, даже не ставя задачу сделать поток выполнения структурным. В Go их задвинули в дальний угол в виде panic, предпочитая возвращать ошибку в коде возврата. В Rust исключений нет, они обходятся специальными типами на основе шаблонов и макросами. В Swift обработку ошибок попытались внешне максимально приблизить к старому подходу с исключениями, но семантически это ближе к подходу Rust. Эта тенденция не имеет отношения к борьбу за структурность, но как видим, к исключениям есть претензии помимо этого.
  • Психология читабельности кода
    0
    TimTowdy уже давал ссылку на материал, из которого взята эта цитата. И я уже приводил 2-ю цитату из этой же статьи, находящейся в следующем абзаце.
    Selection of rules that are most likely to contribute to an increase in reliability maximizes the benefit of adherence while decreasing the necessary effort. Moreover, empirical evidence can give substance to the arguments of advocates of coding standards, making adoption of a standard in an organization easier.
    Это Википедия, пора бы привыкнуть. Отчасти, из-за такой аккуратности в цитировании, несмотря на то, что сами авторы исследования считают, что их эмпиричиеские данные дают аргументы сторонникам MISRA С, ссылающихся на них люди умудряются прийти к прямо противоположным выводам, не читая самого исследования и не понимая к чему относятся слова из цитаты в Википедии.
    И вообще, вы называете «неструктурным» код, в котором структура прослеживается проще.
    Я пользуюсь общепринятой терминологией, которую, возможно, Вам тоже следует изучить прежде, чем что-то брать в кавычки.
  • Психология читабельности кода
    0
    В 70-з не было аргумента «если мои советы вам не подходят, то у вас говнокод». Это ваше новшество.
    А где Вы это увидели, не расскажете? Интересно же. Вы же не станете вводить других в заблуждение?
    Пустые слова, к сожалению. Никакой аналитики вы не привели. А по ссылке которую я привел сходите, там как раз аналитика по MISRA.
    А что Вас смутило даже в этой статье по исследованию 1-го проекта? Это:
    Moreover, empirical evidence can give substance to the arguments of advocates of coding standards, making adoption of a standard in an organization easier. However, correlations and true positive rates as observed in this study may differ from one
    project to the next
    Или что-то другое в отрыве от контекста? Например то, что внесения изменений для соблюдения стандарта в уже готовый отлаженный код приводит к появлению дополнительных ошибок? Так стандарты нужны не для изменений в готовом коде, то есть дополнительных действиях, а для соблюдения во время написания нового без дополнительных усилий.
    Если же полный отказ от break/continue в циклах и try/catch/finally — то это, безусловно, фанатизм.
    Я просто хочу обратить внимание на то, что немногим ранее Вы обвинили меня в том, что я будто-бы утверждаю «если мои советы вам не подходят, то у вас говнокод». А теперь заявляете, что несогласные с Вами — это, безусловно, фанатики. Похоже на зеркалирование собственных поступков, нет?
  • Психология читабельности кода
    0
    «лесенка» растет из-за вложенных if, циклов и switch. Например, здесь «хороший» пример кода с 14-м уровнем вложенности.
    Отличный пример говнокода и беглый просмотр показал, что с ошибками. Ранний выход в нём используется, поэтому точно можно сказать, что его проблемы не в том, что кто-то запретил использовать ранний выход. Его, конечно, можно улучшить, даже если не ставить цель сделать напрашивающуюся декомпозицию и соблюдать структурность. Только это не имеет отношения к вопросу. Впрочем, можете показать Ваш код. А ещё лучше, отправьте его в Microsoft.

    Следовательно, следуя заветам Дейкстры, следует отказаться от раннего возврата. Однако, с тех пор: 1. появилось много языков с автоматическим освобождением ресурсов.
    Во-первых, Вы путаете заветы и доводы. Во-вторых, освобождение ресурсов — это лишь часть ситуаций, где важно соблюдать порядок. Ранее я давал ссылку на эпичный промах Apple, где не было проблемы с освобождением ресурсов, но была проблема с неструктурными переходами. Вы не заметили этого или не придали значения, наверно, отчасти поэтому написали это:
    я не делаю упор на «я так вижу».
    вы делаете упор именно на это.
    Интерпретация чужих слов — это, во многом, вопрос выбора. Ваш выбор таков, это нормально.
    что важнее — факт существования или относительное количество?
    Важно всё. Даже то, каким образом получены данные о количестве. Если методом опроса, то у меня есть плохие новости, если по серии экспериментов и наблюдений, то совсем другое дело.
  • Психология читабельности кода
    0
    Представьте себе, знаком. Вот только сейчас не 70-е
    Зачем мне представлять? Если мой риторический вопрос заключался в указании на то, что это не у меня получается нефальсифицируемая теория, а написана она уже давно на основе практики. То, что о ней пишут с 70-х это не означает, что эти аргументы устарели.
    При фанатичном следовании «классике» Дейкстры придется отказаться не только от multiple return, но и от break/continue в циклах, и от try/catch/finally в языках с исключениями. К счастью, фанатиков нынче не много, да и сам Дейкстра сегодня вряд ли бы поддержал фанатиков.
    Если Вы пишите об этом как о фанатизме, и даже делаете предположения о поддержке со стороны Дейкстры, то это значит, что Вы, как минимум, невнимательно отнеслись к его трудам.
    А вас не смущает что 'эти рекомендации официально допускают отклонения? И что они написаны для конкретной индустрии (embedded), конкретно для С (где памятью приходится управлять вручную)
    Вы незнакомы с MISRA C, иначе бы не стали ничего писать про выделение памяти вручную. А также знали бы, что лишь часть этих рекомендаций специфично для встроенных применений. Единственный выход не относится к ним, а вот неиспользование динамически распределяемой памяти — относится.

    Возвращаясь к теме статьи, я вполне допускаю, что для Вас неструктурный поток исполнения является более читаемым. Но моё мнение основано на анализе ошибок, в том числе и приведшим к уязвимостям, я не делаю упор на «я так вижу».

    Ну и напоследок, как Вы думаете, всё-таки есть люди, для которых структурный поток более читаемый, или это непременно фанатики из 70-х?
  • Психология читабельности кода
    0
    Стоп, а почему вы решили что не может? На мой взгляд все ровно наоборот: в вашем примере заметить опечатку гораздо сложнее
    А Вы попробуйте 1. совершить эту ошибку. 2. не заметить сместившийся блок. 3. Сопоставьте это с изменением потока управления из-за наличия или отсутствия линейного оператора.
    То же самое можно сказать о двух goto в коде Apple
    О том и речь, и это напрямую связано с наличием неструктурных переходов.
    У вас получается нефальсифицируемая теория
    Какая теория? О том, что в заданном вопросе недостаточно информации, для универсального ответа? Или Вас удивляет, что наличие «потребности» в большом количестве неструктурных переходов свидетельствует о проблемах проектирования? Об этом пишут ещё с 70-х. Вы знакомы с классикой Дейкстры? Знакомы с рекомендациями MISRA C для критического к корректности ПО и им подобным? Моя «нефальсифицируемая теория» написана практикой задолго до меня. Но сообщество, к сожалению, ходит по кругу.
  • Психология читабельности кода
    0
    А можете рассказать чуть подробней? Если Вам удалось ужать 5000 строк до 500, то хотелось понять как.
  • Психология читабельности кода
    0
    Вот именно. А не о случайных опечатках
    Отчего же, если в одном случае читаемость потока исполнения выше настолько, что случайная опечатка не сможет пройти незамеченной?
    Как я понял, ваш аргумент состоит в том, что если в функции несколько return, то сложно отследить когда один из них из-за опечатки удалят и это приведет к runtime error
    Нет, речь об очевидности структурного потока. Пример от Apple, приведший к серьёзной уязвимости, был о том же, за тем исключением, что там использовался goto, но это не так принципиально. Ошибка оставалась незамеченной, несмотря на то, что Вы и другие мои критики, считают что неструктурный преждевременный выход лучше читается. В то же время со строго структурным потоком такую ошибку не только было бы сложно допустить, но и была бы она намного очевидней.
    На мой взгляд этот аргумент очень слаб — ведь аналогичных ошибок можно придумать бесконечное множество, и защищать себя от одной ошибки из бесконечности довольно бесполезно
    Мы рассмотрели отдельный аспект, и было бы странно, если бы нам удалось охватить все случаи. Это не защита от одной ошибки, где Вы это увидели? От защиты от ошибок памяти и арифметического переполнения Вы тоже будете открещиваться на том основании, что ошибок можно придумать бесконечное множество?

    И вы до сих пор не ответили: вместо 10 return вы тоже предпочтете сделать 10 уровней вложенных if/else?
    Похоже, я просто не обратил внимание на этот вопрос. Это зависит от задачи. Если в коде встречается виртуальная лесенка из 10 return (а не switch), то скорее всего, там проблема на архитектурном уровне, и надо не потакать ей неструктурными подходами, а решать. Впрочем, всегда надо смотреть на конкретику, для универсального ответа недостаточно данных.
  • Психология читабельности кода
    0
    Весьма странный аргумент.
    Напоминаю, что речь в статье о читабельности.
    Но в любом случае, вот вам аналогичная опечатка в вашем коде
    Во-первых, код не мой, а переделанный Ваш, так как мне было непонятно, почему Вы не записали 1-й вариант так. Во-вторых, ошибка не аналогичная, но тоже отслеживается, хотя и не стандартными средствами Python. Как я уже писал, Python — это отдельная песня.
    Чтобы ошибка была, действительно, аналогичной, она должна была бы выглядеть так:
    def func1():
        results = None
        user = get_user()
        if not user:
            print('no user')
    
        orders = get_orders(user)
        if not orders:
            print('no orders')
        else:
            transactions = get_transactions(orders):
            if not transactions:
                print('no transactions')
            else:
                results = [execute(t) for t in transactions]
        return results
    Как и прежде не видите разницы в читаемости структурного потока и выравненного неструктурного?
  • Психология читабельности кода
    0
    проблема возникает лишь в тех средах, где нет возможности использовать try-finally или его аналоги
    Отнюдь. Освобождение ресурсов это лишь один из примеров, где важна последовательность действий. Растаскивание же порядка действий по defer, try finally и им подобным совсем не улучшает читаемость. А ведь статья об этом. Уменьшения разнообразия переходов положительно сказывается на понятности. Это давно заметили ещё на goto, но этим оператором дело ограничивается.
  • Психология читабельности кода
    –1
    Не совсем понял вопрос. В любом случае, этот вариант меня так же устраивает (за исключением опечаток)
    Дело именно в «опечатках». Статья, напомню, о психологии читабельности, и Ваш комментарий о более лёгком сопровождении.

    Плюс, в таком стиле пишут крайне редко, т.к. он противоречит естественному (позитивному) ходу мыслей. В if обычно пишут позитивное условие, в else — негативное, а не наоборот. Начинать if с отрицания, при наличии else, часто считается code smell.

    А это, тогда что такое?
    if not user:
            print('no user')
            return None

    От того, что в таком случае else неявный, делает только хуже в контексте статьи.
  • Психология читабельности кода
    0
    func2() у вас может упасть
    В этом и суть. Статья о чём? О читабельности. Что читабельней: наличие всех return очевидный поток исполнения?
    В коде func1() надо тщательно читать каждое условие, чтобы понимать где success path
    Не более внимательно, чем в раннем выходе.
    плюс следить за значением results
    Питон это отдельная песня, но при использовании более ошибкоустойчивых языков(+анализатор), корректность работы с result отслеживается. Попробуйте отследить пропущенный return.
  • Психология читабельности кода
    –1
    В приведенном вами коде Apple задача «очистить память перед выходом» стояла изначально
    А если я скажу, что изначально шла работа с локальными буферами и освобождать не нужно было, но в процессе обновления библиотеки понадобилось, то это что-то изменит? Если не стоит запрет на преждевременный выход и я привык его применять, это не увеличит нагрузку на распознавание ситуации, что дальше есть необходимые действия и так поступать нельзя?
    Читать и поддерживать такой код гораздо проще.
    Вот я из большинства поверил Вам, взял этот код и в процессе его более простого сопровождения он стал таким.
    def func2():
        user = get_user()
        if not user:
            print('no user')
    
        orders = get_orders(user)
        if not orders:
            return 'no orders', None
    
        transactions = get_transactions(orders)
        if not transactions:
            return 'no transactions', None
    
        return 'OK', [execute(t) for t in transactions]

    Уменьшилась ли от этого ментальная нагрузка на работу с этой функцией по сравнению со структурным потоком исполнения?
    И, кстати, почему 1-й вариант Вы записали не так?
    def func1():
        results = None
        user = get_user()
        if not user:
            print('no user')
        else    
            orders = get_orders(user)
            if not orders:
                print('no orders')
            else
                transactions = get_transactions(orders):
                if not transactions:
                    print('no transactions')
                else:
                    results = [execute(t) for t in transactions]
        return results
    

    Ведь он же ближе ко 2-му? И что значит прыгать по if/else? Вы действительно прыгаете, затрачивая энергию, а не читаете наглядное ветвление? Может, с непривычки?
  • Психология читабельности кода
    0
    Если он состоит из вложенных if-ов, то он поддаётся декомпозиции. Ранний выход провоцирует на дальнейшее разрастание.

    Про неидеальный мир согласен, но в контекст статьи это не вписывается. Тут, всё-таки, о правильном подходе даже с учётом психологии.
  • Психология читабельности кода
    0
    Про «else if» пример был для самых простых случаях. Обычно это что-то типа
    Тогда нужно разбивать на шаги. Ибо иначе огромные функции так и растут. Из-за усеянности неструктурными переходами разбивать функцию становится всё сложней.

    Как-то, читая новость об исправлении уязвимости в NGINX, случайно обнаружил в нём другую ошибку переполнения. Оцените исправление этой ошибки hg.nginx.org/nginx/rev/e3723f2a11b7 Она была продублирована в большом количестве мест, и общий код не мог быть так просто вынесен в отдельную оттестированную функцию, а был повсюду в большущих функциях, потому что использовалась логика неструктурных переходов, усложняющая декомпозицию.