Эта заметка появилась на свет при размышлении о разработке программного обеспечения как человеческой деятельности. Если в этом плане рассматривать работу программиста, то нужно различать два, как мне кажется, весьма разных её вида: к одной из них программист относится как слуга, а к другой — как хозяин.



Разовьём этот тезис подробнее.

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

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

Естественно, что это различие замечалось многими. Ф.Л.Бауэр [1] называет работу программиста-слуги программированием по контракту. Соответственно можно назвать работу программиста-хозяина программирование для себя. Э.Сандевал [2] развивает близкий подход, выделяя группу «оконечных» программистов. Иногда это различие проводят, употребляя для слуги и хозяина термины профессионального и непрофессионального программирования соответственно. Такая трактовка допустима, если мы будем исследовать социальную сторону программирования как деятельности, например, его профессиональную этику. Если же говорить о программировании, имея в виду его внутреннее содержание, то в этом случае взгляд на программиста-хозяина как на непрофессионала может привести к недоразумениям.

Программист-слуга, в некотором (очень глубоком) смысле, не знает, чего хочет заказчик, и полагается исключительно на формулировку проблемы. Конечно, он не безграмотен, и может знать кучу вещей о предметной области. Он может оказать заказчику неоценимые услуги, обнаружив много несообразностей в его спецификациях. Однако, всё это сверх плана. Его главное и единственное дело — преобразовать спецификацию в надёжный и эффективный результат: программу или данные.

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

Другой облик программирования, тем не менее, тоже существовал всё это время. Будучи повёрнутым в сторону задворок программирования, он однако набирает «второе дыхание» в связи с появлением и развитием персональных ЭВМ. Мало того, системный программист на своей кухне, уставленной инструментальными машинами, часто ведёт себя как хозяин. В этом хозяйстве уже накопились такие средства, как расширяемые языки, макропроцессоры, переписывающие системы, операции периода компиляции, универсальные редакторы и многое другое. Этот ассортимент, однако, сложился случайно и не упорядочен ни хорошей теорией, ни надёжной методологией. Только недавно появился собирательный термин, под который, как под знамя, собираются бессапожные системные программисты, — программная обстановка (programming environment), или — более развёрнуто, но зато более точно для русского языка — операционная обстановка для построения программ. Превратить это модное словоупотребление в стройную методологию с солидным теоретическим обоснованием — важная и увлекательная задача теоретического и системного программирования 80-х годов.

Программист-хозяин знает, что ему надо.

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

Как выразился Дж.Аттарди [3]: «видеть и действовать, а не запоминать и писать». Естественно, что адепты строгого подхода воспринимают это как ересь, однако на самом деле — это новое явление в программировании, которое требует теоретического осмысления и проработки.

Цель этой заметки — изложить вариант теоретической модели программной обстановки, в которой работает программист-хозяин. Эту модель я называю трансформационной машиной (ТМ). Машина поддерживает различные преобразования (трансформации) пар «программа-данные» в пары«программ а-данные». Правильно устроенная ТМ сохраняет функциональный инвариант преобразуемых пар, т.е. если (p?, d?) = t(p, d), где t — трансформация, выполненная машиной, то p?(d?) = p(d).

Другим важным свойством трансформационной машины является то, что она строится самим программистом. Её построение является иерархической конструкцией, и выделенный уровень этой иерархии я, следуя Э.Сандевалу, А.А.Берсу и П.К.Леонову, буду называть контекстом.

Контексту доступны преобразуемая пара (p, d) и набор базовых преобразований, каждое из которых осуществляет элементарное (на этом уровне) преобразование пары (p, d) в другую пару (p?, d?) с сохранением функционального инварианта. Базовые преобразования делятся на три категории — редукции, раскрытия и конверсии. Редукции имеют дело с интерпретацией элементарных (на этом уровне) операций и предикатов, раскрытия раскрывают составные конструкции, а конверсии носят схемно-комбинаторный характер. Примерами редукции являются, например, замена конструкции если ист то А иначе В всё на А или 3+5 на 8. Пример раскрытия — реализация вызова процедуры путём её открытой подстановки, а пример конверсии — перераспределение памяти или экономия совпадающих подвыражений.

Что важно?
Важно, что базовые трансформации могут быть применены свободно. Их применение в произвольной последовательности не нарушает функционального инварианта преобразуемой пары. Это разрешает главную трудность: программист может сделать то, что хочет, не боясь ошибиться. Этого мало. Редукции с раскрытиями и конверсии обладают определённым свойством полноты. Полнота редукций и раскрытий позволяет находить единственным образом нормальные формы пар (p, d), получая их как неподвижные точки базовых трансформаций.

Если функциональным инвариантом пары (p, d) является константа c = p(d), то тогда нормальной формой этой пары будет пара (0, c) с полностью редуцированной программой и с вычисленным результатом в поле данных. Если инвариантом пары (p, d) является
некоторая функция ?(y), то тогда нормальной формой для (p, d) будет пара, программная компонента которой содержит некоторую
остаточную программу для ?, а компонента данных содержит имя аргумента y и (может быть) некоторые константы и имена промежуточных величин.

Конверсии тоже могут обладать свойством полноты по отношению к некоторому схемному инварианту или канонической форме программы и её данных.

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

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

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

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

Программист-хозяин, однако, только тогда сможет хорошо распорядиться предоставленной ему свободой действий, если будет хорошо видеть поле для их применения. Большой и чёткий экран дисплея нужен программисту так же, как широкое и чистое ветровое стекло автомобилисту. Но если за ветровым стеклом действительность сама подставляет водителю дорожные знаки и ситуации, то для системного программиста нужно ещё много потрудиться, чтобы превратить подслеповатые литеры алфавитно-цифровых дисплеев в компактное и наглядное изображение программ и данных. Хотелось бы обратить внимание читателя на некоторые новые принципы взаимодействия человека с машиной, выдвигаемые так называемыми объектно-ориентированными языками, из которых в первую очередь надо выделить язык Смолток [5].

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

1. Bauer F.L. Programing as fulfilment of a contract. — In: «Infotech state of the art reports, Series 9, No.6. System Design». — Maidenhead: Pergamon Infotech, 1981, p. 167–174.
2. E.Sandewall. An environment for development and use of executable application models. — In: Records of the 2nd Software Technology Seminar, Capri, May 3–7, 1982, p. 12+43p
3. Attardi G. Office information systems desing and implementation. — (Technical report) Cnet No.47. Instituto di Scienze dell’Informazione Univers. di Pisa, Pisa, 1980, 44p.+ii.
4. Ершов А.П. Смешанные вычисления: потенциальные применения и проблемы исследования. — В кн.: Методы Математической логики в проблемах искусственного интеллекта и систематическое программирование. Тезисы докладов и сообщений. Часть 2. В надзаг.: Ин-т математики и кибернетики АНЛитССР. Вильнюс, 1980, с.26–55.
5. Ingalls D.H. The Smalltalk-76 programming system: design and implementation. — In: Proceedings of the 5th Annual ACM Symposium on Principles of Programming Languages, 1978.

1982
Из Архива Ершова [источник]

Комментарии (11)


  1. gena_glot
    21.04.2016 03:48

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

    «если (p?, d?) = t(p, d), где t — трансформация, выполненная машиной, то p?(d?) = p(d)». непонятна логика здесь с т.з. математики. Давайте уберем программа и данные и введем мат.функции и вы увидете что контрпример легко построить.

    То есть:
    (p',d') = t(p,d) при этом p'(d')<>p(d)
    Это ошибка, не знаю может в вашем случае не возникает.


    1. mayorovp
      21.04.2016 12:46
      +1

      Дело не в спецификации, а в постановке задачи.

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

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


      1. click0
        21.04.2016 21:42

        Это уже постановка задания с неявными условиями :)


      1. Bokhan
        22.04.2016 13:12

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


        1. mayorovp
          22.04.2016 16:43

          У программиста-хозяина нет заказчика.


          1. Bokhan
            22.04.2016 16:56

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


            1. mayorovp
              22.04.2016 17:09

              Да. А у вас что, какое-то другое понимание слова «хозяин»?


              1. Bokhan
                22.04.2016 17:21

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


                1. mayorovp
                  22.04.2016 17:23

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


                  1. Bokhan
                    22.04.2016 17:31

                    У меня есть два знакомых разработчика: один фронт-эндщик, другой бэк-эндщик, оба в свободное от работы время не разрабатывают ничего. Их можно считать программистами-хозяевами? Думаю, нет.
                    Вообще, если подумать, людей в IT можно поделить на энтузиастов и неэнтузиастов. Вторые разрабатывают потому, что за это платят, это круто, и т.д. Первые, помимо того, разрабывают потому, что получают удовольствие от этого.
                    Так вот, первые да, скорее всего в свободное время творят (в хорошем смысле) то, что хотят. Вторым же это не нужно и они вполне могут себе позволить делать только то, что нужно.
                    Кстати, спорный вопрос — если в свободное время я развиваю некий проект, который мне неинтересен, но очень нужен мне или «всем» — считаюсь ли я программистом-хозяином?


  1. KyHTEP
    23.04.2016 15:35
    +1

    С такой точки зрения человек, который нарисовал картину, слуга или хозяин?
    Абстрактно, субъект придумавший методологию слуга или хозяин?
    Ошибка, как мне кажется, в самой постановке вопроса. Хозяин или слуга. Есть задача, ее надо решить. Решивший — пусть назовем его, инженер, удачно подходит, без привязки к эмоциональной части.