Pull to refresh

Comments 80

PinnedPinned comments

Затронутая проблема скорее всего не в перепутанных причине и следствии, а в некорректном обобщении.

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

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

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

А проверки на "ограничения на водные параметры" это входит в алгоритм или постулируется?
Если второе, тогда может получиться как в анекдоте "станьте ёжиками", когда есть требования к входным параметрам, но в реальности они не достижимы.

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

Программисты старой школы всё ещё пишут условные if(ptr==nulltpr) return E_INVALID;

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

Ошибка - тоже результат, да и обработку ошибок тоже вполне легко можно представить в структурном подходе. (Без перехвата исключений - это будет вообще тривиально)

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

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

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

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

Исключения - это очень минималистичный способ в сравнении с предложением от ФП.

что типы данных плохо описывают сущности с которыми работает программа.

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

Выражаясь фигурально...

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

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

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

Именно так построена обработка ошибок в языке Go.

На кой чёрт нужен алгоритм, если он нежизнеспособен в реальности и его прямо надо допиливать?

Алгоритм - это "костяк". Какое "мясо" на него налепят в реальности - не его проблемы.

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

Не путайте алгоритм с теорией. Последняя допускает ответвления и вольные трактовки, но не алгоритм.

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

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

Это не "алгоритм", а вульгаризация понятия "алгоритм" для кодеров.

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

А то, о чём говорите вы, не алгоритм, а реализация алгоритма каком-то кодом на каком-то языке программирования. И допиливают, чаще, не алгоритм, а код. И не потому, что алгоритм ошибочен, а потому, что в коде напахали.

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

Цитат из этой самой статьй в Википедии.

Алгоритм может быть просто на словах (взять деньги, идти в магазин, купить буханку хлеба, вернуться домой).

Нет, это не алгоритм. Известный ролик на данную тему: https://www.youtube.com/watch?v=cDA3_5982h8
А в программировании "алгоритм" имеет именно математический смысл, т.к. для любой программы можно построить эквивалентную машину Тьюринга.

Алгоритм - это термин со строго определенным значением и в его определении никогда не было упоминания про машину Тьюринга.

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

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

Если алгоритм состоит из команды "намазать масло на хлеб", то постановщик задачи (программист) должен понимать, какими терминами он может оперировать.

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

Полагаю, вы не знакомы с теорией алгоритмов? В которой понятие "алгоритм" аксиоматически определяется через понятие "абстрактный исполнитель" (абстрактная вычислительная машина). Классическим абстрактными исполнителями являются: лямбда-исчисление, машина Тьюринга, машина Поста, нормальные алгорифмы Маркова.
Любая компьютерная программа реализует именно это строго математическое определение понятия "алгоритм" и никакие иные "алгоритмы", выходящие за рамки математической теории алгоритмов, в цифровых дискретных вычислительных системах невозможны.

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

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

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

Тогда как я привожу определение алгоритма с точки зрения постановщика задачи (человека). У него есть только последовательность шагов (правил), которые нужно выполнить на "абстрактном исполнителе", но сам исполнительно не конкретизирован.

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

Наверно из-за этого у нас с вами и получаются разные выводы при определении понятия алгоритм, хотя мы имеем ввиду одно и тоже, просто смотрим на определение алгоритма с разных сторон.

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

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

А исключения по сути -- это аналог goto (куда-то) вверх по стеку.

Исключения ещё можно на континуациях сделать.

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

Структурное программирование выстрелило в связи с большими сложностями IBM при создании первой большой ОС - они еле сумели её выпустить. Тогда и были продекларированы запреты на спагетти-код и, как следствие, на goto.

Проблема давно ушла, а страхи всё ещё остались :-)

Много математики потребовало функциональное программирование.

А императивщина это так: тяп ляп

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

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

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

UFO just landed and posted this here

Так в статье и от goto не предлагается отказываться. Там говорится, что эти конструкции могут менять состояние программы, что вредит автоматическому выводу доказательства её правильности.

UFO just landed and posted this here

Ну хорошо, путь будет ваша формулировка т.е. не "отказаться", а "ограничимся рассмотрением языков программирования без операторов присваивания и перехода".

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

Согласитесь, было бы очень странно, если бы критиковались операторы присвоения. Как бы тогда вообще программы приходилось бы составлять? То ли дело goto, который легко заменить всякими break, continue и пр. (если что, это сарказм)

А вот если обратится к первопричине (что эти управляющие конструкции меняют поведение линейного алгоритма), то мне кажется разумней было бы не гнобить goto,а продвигать принцип SSA (Static single assignment), который упрощает автоматизацию обработки и гереации кода с операторами присвоения. Жаль, что его разработали гораздо позже.

UFO just landed and posted this here

Если гнобить goto, то и if тоже надо гнобить. If - это условный goto под себя.

Претензия к goto заключалась в том, что он передаёт управление далеко по тексту, то есть в каком-то смысле нарушает локальность.

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

Это очень странная логика)

Понятно, что if под капотом и есть условный goto и в целом это сахар, но так за это его и любят)

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

Странная, зато повышающая шанс открыть новые направления в обсуждении.

это очень ограниченный goto "только вперёд", в отличие от нормального, который в обе стороны.

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

Структурное программирование - это декларируемый подход. Парадигма, т.е. Как эта парадигма будет реализована в конкретных ЯПВУ - отдельный вопрос. А как на этих языках будет написана конкретная программа - совсем уже третий.

Ситуация напоминает ту, что сложилась с сетевыми протоколами. Есть декрарируемая семиуровневая модель OSI. А есть ее реализация - четырехуровневый стек протоколов TCP/IP. В нем одни уровни объединены, а другие - пересекаются. Но, тем не менее, стек TCP/IP не отрицает модель OSI, а базируется на ней и служит ее конкретной реализацией.

Другой пример - язык Pascal. Не тот, который Object, а который просто. Создавался именно в соответствии с парадигмой СП, но дополняет её более сложными операторами ветвления, оператором выбора, различными формами операторов цикла, операторами break, continue и даже goto.

И, кстати, все эти операторы (ну, кроме goto) прекрасно вписываются в понятие структурного программирования.

Если занудствовать, то в “просто паскале” не было break и continue. Но goto был. Вирт тогда не решился сразу на радикальный шаг, но впоследствии убрал goto из Модулы.

Таки, да. Сейчас поискал в Интернете, нашел, что операторы "break" и "continue" были введены в Turbo Pascal 7.0 в 1992 году.

Давненько было. Хоть я начинал знакомство с Паскалем еще с третьей версии, но как там обстояло дело - не помню.

Мне одному кажется, что цикл это и есть ветвление?

Нет, не одному. Но в этом случае пришлось бы использовать не кошеный goto, а он фууууу, бяка :-)

Разработчики на Fortran до версии IV включительно скорее всего с этим утверждением согласятся (по крайней мере те кто еще с нами)

Цикл ведь может быть бесконечным, т.е. безусловным.

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

Исключения это тот же GOTO

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

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

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

Вместо исключений - монады maybe|result как в Расте или просто err как в Го, вместо return - возвращаем последнее значение из функции как в том же Расте. Удобно ли так писать? Вопрос открытый. Но то что так можно делать реальный софт - это факт

Затронутая проблема скорее всего не в перепутанных причине и следствии, а в некорректном обобщении.

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

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

Мне всегда казалось, что в "школьном" контексте фраза о том, что достаточно трёх видов конструкций приводится чтобы доказать, что без goto в принципе можно обойтись. Иными словами, исключая goto из арсенала, вы формально ничего не теряете. Опять же, формально тут всё справедливо: любое эффективное вычисление можно представить в виде машины Тьюринга, которая, очевидно, может быть реализована без goto. При этом, разумеется, можно придумать основанный на хитрых goto переходах алгоритм, который будет практически довольно сложно преобразовать в эквивалент без них.

Если не ошибаюсь, в PL/1 были переменные типа "метка". Т.е., им можно было присвоить различные точки перехода goto динамически в процессе исполнения программы.

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

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

Не совсем понял комментария - вы можете привести пример алгоритма, который не реализуется на машине Тьюринга?

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

Но позвольте, мне совершенно не очевидно, да и в Вики написано, что Машина Тьюринга является расширением конечного автомата и, согласно тезису Чёрча — Тьюринга, способна имитировать всех исполнителей (с помощью задания правил перехода).

Может быть вы приведите пример машины Тьюринга без goto?

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

Машина Тьюринга тривиально реализуется без goto. Что-то в этом роде:

rules = { (0, 0): (1, 2, 1), (1, 3): (5, 2, -1), ... }
tape = [0, 6, 1, ...]
state = 0
pos = 0

while tape[pos] != 'HALT':
    state, tape[pos], move = rules[(state, tape[pos])]
    pos += move

"Правила перехода" -- это функция машины, а не эмулятора, который эту машину рализует.

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

Обработка прерываний и параллельное выполнение не являются алгоритмическими задачами.

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

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

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

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

В реальном мире приходится заниматься много чем и помимо программирования. Изначальный контекст вашей заметки в том, что, дескать, Дейкстра (а точнее, Бём/Якопини) воспринимаются "как-то не так", потому что игнорируют реальность, в которой есть параллельный код, стирка белья и окучивание грядок. Это довольно странное замечание, потому что вся дискуссия Дейкстры и прочих идёт в рамках пространства теории вычислений, где понятие алгоритма (как машины Тьюринга) подразумевается и не вызывает разночтений.

Что касается недетерминированной машины Тьюринга, она эмулируется на детерминированной (за O(2^N)), поэтому в данном контексте её особенности неважны.

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

ОК, хорошо. Штука в том, что фраза "все наверно помнят, что любой алгоритм можно представить в виде трех видов алгоритмических конструкций, следование, ветвление и повторения?", с которой вы полемизируете, совершенно справедлива. Вы пишете, что в эту концепцию не вписываются исключения, и что с того? Исключения не являются частью этой дискуссии.

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

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

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

Вы пишете, что в эту концепцию не вписываются исключения, и что с того? Исключения не являются частью этой дискуссии.

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

Штука в том, что алгоритм = машина Тьюринга. Если вы под словом "алгоритм" (aka вычислительный алгоритм) понимаете что-то другое, то с чего бы? Это уже как раз ваш разговор с собой получается, потому что у Дейкстры ровно так.

если принять что исключения - это "выключения питания", то

1) не надо добавлять отдельные средства работы с ними

2) можно обрабатывать любые вложенные скобки как источник "тут кто-то выключил питание" в виде обычного алгоритма (только на "уровне сверху").
3) если действительно кто-то выключил питание - у вас есть есть возможность написать алгоритм (но понадобится система его исполнения :) )

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

ну, я понимаю, что это не настоящее выключение.

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

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

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

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

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

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

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

это всего лишь надстройка над поведением

В этом я с вами полностью согласен! Если при формулировании задачи пишем, что-то вроде "при возникновении ошибки или исключения - прервать работу и вернуть управление оператору", тогда действительно обработка ошибок будет не нужна, т.к. перекладывается на уровень выше (на оператора).

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

но это все равно не алгоритм задачи, а алгоритм восстановления после сбоя :)

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

PS: если что - мне просто интересно общаться :) Если вам покажется что у меня неправильный тон размышления и подачи вопроса - пишите, я попробую его сменить :sweat_smile:

Вы просто говорите про алгоритмы разного уровня, но от этого они не перестают быть алгоритмами :-)

PS: если что - мне просто интересно общаться :) Если вам покажется что у меня неправильный тон размышления и подачи вопроса - пишите, я попробую его сменить :sweat_smile:

Общаться по теме всегда хорошо, ибо только "в споре рождается истина".
Более того, несколько идей я протестировал в статьях и комментариях к ним и даже поделился таким не хитрым способом с читателями Хабра.

1) да, это все алгоритмы
2) но это разные алгоритмы - одни решают задачу, а вторые обслуживают решателя

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

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

настоящее решение еще нас ждет в каком-то будущем языке программирования :)

Согласен, в каком нибудь новом языке программирования :-)

Как я понимаю, речь шла не о присвоении значений переменным вообще , а о так называемом "side effect" ( недеклрируемое явно изменение состояния системы внутри фунции ) при вызове функций мешающему отладке и вызывающему неопределённое поведение.

следование, выбор и повторение

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

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

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

В своей публикации на хабре я описал свою систему программирования тестов, в которой используется только линейный и циклический алгоритм. Xотя я и включил в систему команд оператор Go to, но использовать его в программе теста было неудобно, так как автоматический выход из цикла был не нужен, гораздо удобнее было привязать операцию с параметром к номеру цикла и использовать параметр- указатель пропустить команду в цикле или выполнить. Go ТО для выхода из цикла оказался не нужен. Тем более не нужен в линейной части алгоритма, так как if за ненадобностью не поддерживался. Только линейный и циклический алгоритм успешно решил все задачи. Для отладки программы был предусмотрен переход на любой оператор программы теста только в ручном режиме, примерно также как в IDE ЯП.

Sign up to leave a comment.

Articles