All streams
Search
Write a publication
Pull to refresh
1
0
Константин @Comdiv

Программист

Send message
В этой статье, кстати, не говорится, что в языке Пираха нет рекурсии. Речь об особом типе рекурсии, которую автор статьи называет рекурсией Хомского, и, вообще, проходится по этому очень поверхностно. Поэтому утверждение
идея универсальной грамматики была сильно подмочена, когда разобрали язык индейцев пираха, в котором нет рекурсии.
как минимум не точно.
Рекурсия нужна для возможности выражения более сложных вещей, чем без неё. Это не опровергает универсальную грамматику также, как наличие подмножества не опровергает наличие полного множества — как регулярные выражения не опровергают контекстно свободные грамматики.
Неплохой домашний СОРМ получился
После того, как все поголовно стали пользоваться мобильным СОРМ, не смешно.
Блокирующее I/O это то, которое возвращает управление только тогда, когда весь запрашиваемый блок данных был получен или уже не может быть получен.
Интринсики, скорее, продолжение языка компилятора. Он обрабатывает их по особому, не как обычную библиотеку.
Надо уточнить, что речь про блокирующее I/O. На неблокирующем разницы не будет.
Проблема в самих дробях. В крайнем случае придётся заниматься факторизацией длинных(>2^64) чисел, при этом потребность в памяти всё равно может расти из-за простых числителя и знаменателя. Итого — потенциальная бомба по памяти и вычислительной сложности в задачах настоящего времени. Это помимо того, что существуют иррациональные числа — действительные числа, непредставимые в виде простой дроби. Довольно безумно.
Не знаю, почему Вам показалось, что эти языки были приведены для доказательства рекомендаций, появившихся до 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.

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

Это они чушь какую-то написали, не посоветовавшись с Вами?
да.
Это, как раз, означает, что Вы придумываете свои собственные понятия, и Ваше понимание единственного выхода противоречит общепринятому.
Загляните ещё в английскую Википедию
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.
Это они чушь какую-то написали, не посоветовавшись с Вами?
Понятия «структурный поток выполнения» не существует так же, как и не существует понятия «неструктурный код» в контексте кода, использующего early return. Хватит придумывать новый термин каждый раз когда заканчивается аргументация.
Структурный поток выполнения — это не новый термин, придуманный мной, а всего лишь сочетание слов, которые я использовал как синоним для кода, написанного в соответствии с принципами структурного программирования. Я вижу, это Вас смущает, но таковы особенности обычного человеческого языка — они позволяют достаточно вольно обращаться со словами. Я так понимаю, Вы сконцентрировались на принципе «один вход — один выход», поэтому упустили из виду, что он не исчерпывающий, отсюда и недопонимание.
Для доказательства актуальности гайдлайнов, появившихся до си, пример крайне неудачный
Не знаю, почему Вам показалось, что эти языки были приведены для доказательства рекомендаций, появившихся до C(особенно MISRA C, конечно), так как я сразу написал, что в них даже не ставили задачу сделать код структурным. В действительности, это было ответ на это:
Значит ли, что стоит убирать исключения из всех яп их использующих? Нет.
Вопрос был задан так, будто это совсем уже что-то безумное. А как видим, нет — исключение исключений стало банальным действом.
превосходный совет, рекомендую
Но сами Вы им не воспользовались, потому что то, что Вы описали не имеет отношение к структурному потоку выполнения. Всё-таки, неплохо бы почитать про структурное программирование, хотя бы и на Википедии.
Опять же, механизм исключений, появившийся позже, противоречит принципу sese. Значит ли, что стоит убирать исключения из всех яп их использующих? Нет.
Из уже используемых языков ничего удалять нельзя, можно только добавлять — такова логика развития языка.

В новых же языках исключения начали убирать, даже не ставя задачу сделать поток выполнения структурным. В Go их задвинули в дальний угол в виде panic, предпочитая возвращать ошибку в коде возврата. В Rust исключений нет, они обходятся специальными типами на основе шаблонов и макросами. В Swift обработку ошибок попытались внешне максимально приблизить к старому подходу с исключениями, но семантически это ближе к подходу Rust. Эта тенденция не имеет отношения к борьбу за структурность, но как видим, к исключениям есть претензии помимо этого.
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 С, ссылающихся на них люди умудряются прийти к прямо противоположным выводам, не читая самого исследования и не понимая к чему относятся слова из цитаты в Википедии.
И вообще, вы называете «неструктурным» код, в котором структура прослеживается проще.
Я пользуюсь общепринятой терминологией, которую, возможно, Вам тоже следует изучить прежде, чем что-то брать в кавычки.
В 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 — то это, безусловно, фанатизм.
Я просто хочу обратить внимание на то, что немногим ранее Вы обвинили меня в том, что я будто-бы утверждаю «если мои советы вам не подходят, то у вас говнокод». А теперь заявляете, что несогласные с Вами — это, безусловно, фанатики. Похоже на зеркалирование собственных поступков, нет?
«лесенка» растет из-за вложенных if, циклов и switch. Например, здесь «хороший» пример кода с 14-м уровнем вложенности.
Отличный пример говнокода и беглый просмотр показал, что с ошибками. Ранний выход в нём используется, поэтому точно можно сказать, что его проблемы не в том, что кто-то запретил использовать ранний выход. Его, конечно, можно улучшить, даже если не ставить цель сделать напрашивающуюся декомпозицию и соблюдать структурность. Только это не имеет отношения к вопросу. Впрочем, можете показать Ваш код. А ещё лучше, отправьте его в Microsoft.

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

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

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

И вы до сих пор не ответили: вместо 10 return вы тоже предпочтете сделать 10 уровней вложенных if/else?
Похоже, я просто не обратил внимание на этот вопрос. Это зависит от задачи. Если в коде встречается виртуальная лесенка из 10 return (а не switch), то скорее всего, там проблема на архитектурном уровне, и надо не потакать ей неструктурными подходами, а решать. Впрочем, всегда надо смотреть на конкретику, для универсального ответа недостаточно данных.
Весьма странный аргумент.
Напоминаю, что речь в статье о читабельности.
Но в любом случае, вот вам аналогичная опечатка в вашем коде
Во-первых, код не мой, а переделанный Ваш, так как мне было непонятно, почему Вы не записали 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
Как и прежде не видите разницы в читаемости структурного потока и выравненного неструктурного?
проблема возникает лишь в тех средах, где нет возможности использовать try-finally или его аналоги
Отнюдь. Освобождение ресурсов это лишь один из примеров, где важна последовательность действий. Растаскивание же порядка действий по defer, try finally и им подобным совсем не улучшает читаемость. А ведь статья об этом. Уменьшения разнообразия переходов положительно сказывается на понятности. Это давно заметили ещё на goto, но этим оператором дело ограничивается.

Information

Rating
Does not participate
Location
Киев, Киевская обл., Украина
Registered
Activity