Концепция жизни программы

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


    design


    Когда появляется программа? Скорее всего, программа появляется в голове у проектировщика/разработчика, можно назвать это design-time. Но так как этот момент не поддаётся контролю компьютера (пока), то предположим, что моментом появления программы является момент создания минимального запускаемого (о подробном смысле этого термина стоит поговорить отдельно) исходного кода.


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


    Можно обоснованно выделить design-time в отдельную категорию, но не как процесс в голове разработчика, а чисто утилитарно, опираясь на процесс кодирования. Здесь можно описать автокомплит, автоподсветку (как уже реализованные программы), программирование макросов ide, генерацию схем БД и ДРАКОН-схем, и так далее.


    compile


    Затем, после этапа написания некоторого программного кода, программа передается компилятору. Компилятор обеспечивает т.н. compile-timeвремя компиляции. В результате выполнения процесса компиляции мы получаем компилят (то есть непосредственный результат обработки нашего исходного кода).


    Во время компиляции наш исходный код влияет на работу компилятора по определенным законам, которые выражены в коде компилятора.


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


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


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


    load


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


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


    На данный момент известна только одна технология, WebAssembly (slim-binaries), поздняя кодогенерация на целевой платформе, которая хоть как-то описывает время загрузки.



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


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


    Мало что известно про выполнение кода во время связывания, однако понятно, что в момент связывания возможно выполнение кода, например, Dependency Injection и динамического наследования/проксирования, как это может быть реализовано в рамках работы внутри jvm.


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


    init, run, close


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


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


    Такой подход снижает требования к среде исполнения (run-time environment) но не дает гарантий исполнения того или иного этапа в нужной последовательности из-за возможных ошибок исполнения (run-time error) после которых исполнение, обычно, должно завершиться аварийно.


    death


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


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


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


    Итоги


    Итак, рассмотрены этапы жизни программы: design-time -> compile-time -> load-time -> link-time -> init-time -> run-time -> close-time -> death-time. Как можно заметить, все этапы присутствует в цикле разработки и использования любой программы, а значит в любой из этих этапов может быть выполнен пользовательский код, который позволит получить результат, наиболее соответствующий целям разработчика. На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.

    Only registered users can participate in poll. Log in, please.

    В каком из этапов вам не хватает возможности исполнения пользовательского кода?

    Share post

    Similar posts

    Comments 10

      0
      До трёх таймов я бы сократил. design,compile,run
        +1
        Пользовательский код в голове у разработчика?

        Заголовок спойлера
        image

        По-моему, я только что прочёл эталонную хрень.
          –1
          > На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.

          https://ru.m.wikipedia.org/wiki/UML
            0
            Нравится подход.

            Беда в том, что контексты меняются. Написал например на windows, собрал на mac, запустил и закрыл на iOS, получил push-уведомление…

              +1
              Когда появляется программа? Скорее всего, программа появляется в голове у проектировщика/разработчика, можно назвать это design-time. Но так как этот момент не поддаётся контролю компьютера (пока), то предположим, что моментом появления программы является момент создания минимального запускаемого (о подробном смысле этого термина стоит поговорить отдельно) исходного кода.
              Не понял, что значит не «поддаётся контролю компьютера»? О каком контроле речь? О размере какого-то рабочего файла? Нет ли тут ошибки обобщения, когда пусть из частых, но частных случаев, пытаются сделать общий вывод? Нпр., работа над программой компилятора с языка Х может начаться с описания этого языка на BNF, а может с поиска подходящего языка в Инете (есть задача, для которой нужен спец. язык с определенными свойствами). Далее по BNF может быть сделано задание для Yacc, а может написание кода на универсальном ЯП в полном объеме, а может в минимальном + компилятор Х, написанный на Х, с последующей раскруткой по Вирту и др. Но до этого может быть длительный этап обсуждений, сравнений измерений и т.д. А в другой задаче может быть нужен хитрый алгоритм. И снова поиск, а если не удалось найти, то разработка алгоритма. В результате алгоритм м.б. записан на псевдокоде, а далее последуют работы по мат. доказательству корректности этого алгоритма и его теоретическим оценкам. И.т.д. ИМХО у ПО разного типа бывает разное рождение.
                0
                Речь о более общем контроле, на данном историческом этапе компьютер не может задизайнить (разработать, создать, довести до необходимого состояния, короче) программу по ТЗ самолично, без участия программиста.

                Поэтому возможности «исполнителя» (компьютера) на первом этапе ограничены возможностями IDE, которую можно дополнить пользовательским кодом в виде плагинов. Как раз этот код подлежит исполнению в design-time.

                Например, сгенерированный по WSDL-описанию java-класс будет слегка бесчеловечным, что определит дальнейшую работу с этим классом, а значит, повлияет на программу в целом.
                0
                > На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.
                Автор какой-то сферический демагог в вакууме. Как это нету? А всё, что окружает вас? Вообще всё? Любая программа, которая не крашится и не засирает систему, не оставляет после себя следов. Которая просто работает и выполняет свою задачу. Как это нету-то?
                  +1

                  Автор хочет выполнять произвольный код во время (например) линковки. Как к этому относятся программы, которые "не крашатся и не засирают систему"?


                  Нужно ли это — другой вопрос.

                  0
                  рассмотрены этапы жизни программы: design-time -> compile-time -> load-time -> link-time -> init-time -> run-time -> close-time -> death-time

                  Какая-то каша из разработки ПО и выполнения программы. Программа ведь не один раз запускается, а по схеме — один.


                  Если брать жизненный цикл ПО, его этапы примерно такие: 1) сбор требований; 2) проектирование, реализация, отладка; 3) внедрение; 4) поддержка; 5) замещение другой системой. Этапы могут пересекаться.


                  У "жизненного цикла" программы (процесса?) этапы уже 1) инициализация; 2) выполнение; 3) финализация.


                  Для чего это смешивать?

                    0
                    Нет, это именно жизнь программы, исполняемой компьютером, смартфоном, браузером, исполнителем, короче. Жизненный цикл у неё состоит из повторения последовательности этапов, которые я описал.
                    Возможно, вас смутило созвучие с «жизненным циклом ПО». Надо было явно обозначить «цикл».

                  Only users with full accounts can post comments. Log in, please.