Старые секреты быстрой отладки: анимация исходного кода

    Вечер пятницы часто оказывается вечером воспоминаний, и не только о прошедшей неделе, но и о гораздо более ранних событиях. В эту пятницу вспомнил об одной интересной программе для MS DOS (а также для Mac OS, UNIX и VAX/VMS) – Паскаль-интерпретаторе и IDE Dr. Pascal. Подробную информацию о возможностях и отзывы можно найти на сохраненном в архиве сайте изготовителя Visible Software (США), а я ограничусь только наиболее запомнившимися мне идеями, причем эти идеи, на мой взгляд, даже сегодня не утратили актуальности. Прежде всего вспоминается картинка:

    image

    Позже мы вернемся к этой картинке, а пока начнем с начала, т.е. с основного меню:

    image

    Как видим, меню достаточно обычное для DOS-программы. Загружаем файл широко известной задачки

    «8 ферзей»:
    program EightQueens(output);
    { Place 8 hostile queens on a chessboard, such that none can be captured. }
    { From Wirth:  Algorithms + Data Structures = Programs, page 146. }
      var
        i: integer;
        RowFree: array [1..8] of boolean;
        UpDiag: array [2..16] of boolean; { diagonal to upper right }
        DownDiag: array [-7..7] of boolean; { diagonal to lower right }
        QueenIn: array [1..8] of integer;
    
    
      procedure print;
      { Write out one solution }
        var
          k: integer;
        begin { print }
          for k := 1 to 8 do
            write(QueenIn[k]: 4);
          writeln;
        end { print };
    
    
      procedure try(col: integer);
      { Try to place a queen in this column }
        var
          row: integer;
        begin { try }
          for row := 1 to 8 do
            if RowFree[row] and UpDiag[col+row] and DownDiag[col-row] then
              begin
                QueenIn[col] := row;
                RowFree[row] := false;
                UpDiag[col+row] := false;
                DownDiag[col-row] := false;
                if col < 8
                  then try(col+1)
                  else print;
                RowFree[row] := true;
                UpDiag[col+row] := true;
                DownDiag[col-row] := true;
              end;
        end { try };
    
      begin { EightQueens }
        for i := 1 to 8 do
          RowFree[i] := true;
        for i := 2 to 16 do
          UpDiag[i] := true;
        for i := -7 to 7 do
          DownDiag[i] := true;
        try(1)
      end { EightQueens }.
    


    и нажимаем F9 (Run). Исполнение программы отображается на экране:

    image

    Внизу результаты, выводимые программой (output), выше слева фрагмент кода исполняемой на данном шаге процедуры (или функции), где стрелочкой отмечен исполняемый оператор, справа – значения актуальных в данный момент переменных, выше – то же самое для вызвавшей процедуры. При этом переход с оператора на оператор происходит автоматически с заданной пользователем задержкой – такое «кино» останавливается по окончании загруженной в IDE программы (в нашем случае «8 ферзей») или по команде Freeze, которую можно отдать, нажав соответствующую функциональную клавишу. Если программа не кончилась, то дальше можно двигаться пошагово, как в других отладчиках, нажимая стрелку вниз, или вернуться в «кино», нажав F8 (Continue). Во второй строке сверху экрана отображается цепочка вызовов процедур. Особо стоит отметить, что упомянутые выше «актуальные в данный момент переменные» Доктор выбирает сам, пользователю нужно только загрузить программу и нажать Run. Судя по отзывам, такое предельно простое управление оказалось очень удобным для вводных студенческих курсов по основам программирования, для чего Dr. Pascal, собственно, и предназначен. Однако в инструкции пользователя отмечается, что и для продвинутого профессионального программиста быстрая возможность одним движением посмотреть, как работает небольшая программа, может оказаться полезной. Тут возникает интересный вопрос: а насколько небольшая?

    Я взял Виртовский интерпретатор PascalS, написанный на Паскале. По сравнению с ферзями это программа, объемом около 2000 строк исходного кода, гораздо сложнее. Доктору она в изначальном виде оказалась не по силам, поэтому я разрезал ее на две части.

    Первая часть подготавливает файлы данных:
    {%F- no reformatting }
    {%O+}
    program Pas1 (input,output,paskey,pasksy,spsfile,enterf,symsetf{,textf});
    
    const
       nkw = 27;     (*no. of key words*)
       alng =  10;   (*no. of significant chars in identifiers*)
    type
       symbol = (intcon,realcon,charcon,string,
                      notsy,plus,minus,times,idiv,rdiv,imod,andsy,orsy,
                      eql,neq,gtr,geq,lss,leq,
                      lparent,rparent,lbrack,rbrack,comma,semicolon,period,
                      colon,becomes,constsy,typesy,varsy,functionsy,
                      proceduresy,arraysy,recordsy,programsy,ident,
                      beginsy,ifsy,casesy,repeatsy,whilesy,forsy,
                      endsy,elsesy,untilsy,ofsy,dosy,tosy,downtosy,thensy);
           alfa = packed array [1..alng] of char;
           object = (konstant,variable,type1,prozedure,funktion);
           types = (notyp,ints,reals,bools,chars,arrays,records);
      keytype = array [1..nkw] of alfa;
      ksytype = array [1..nkw] of symbol;
      spstype = array [char] of symbol;
      symset = set of symbol;
      entertype = record
                   fx0: alfa; fx1: object;
                   fx2: types; fx3: integer;
                  end;
    
       var
           key: keytype;
           ksy: ksytype;
           sps: spstype; (*special symbols*)
           syset : symset;
           pasksy  : file of ksytype;
           paskey  : file of keytype;
           spsfile : file of spstype;
           enterf  : file of entertype;
           symsetf : file of symset;
    {       textf   : text;}
    
    procedure enter(x0: alfa; x1: object;
                    x2: types; x3: integer);
    
    var
      EnterRec : EnterType;
    
    begin
      with EnterRec do
         begin  fx0 := x0; fx1 := x1;
            fx2 := x2;  fx3 := x3
         end;
      write ( enterf, EnterRec );
    end (*enter*) ;
    
    begin   {main program}
       key[ 1] := 'and       '; key[ 2] := 'array     ';
       key[ 3] := 'begin     '; key[ 4] := 'case      ';
       key[ 5] := 'const     '; key[ 6] := 'div       ';
       key[ 7] := 'do        '; key[ 8] := 'downto    ';
       key[ 9] := 'else      '; key[10] := 'end       ';
       key[11] := 'for       '; key[12] := 'function  ';
       key[13] := 'if        '; key[14] := 'mod       ';
       key[15] := 'not       '; key[16] := 'of        ';
       key[17] := 'or        '; key[18] := 'procedure ';
       key[19] := 'program   '; key[20] := 'record    ';
       key[21] := 'repeat    '; key[22] := 'then      ';
       key[23] := 'to        '; key[24] := 'type      ';
       key[25] := 'until     '; key[26] := 'var       ';
       key[27] := 'while     ';
       ksy[ 1] := andsy;         ksy[ 2] := arraysy;
       ksy[ 3] := beginsy;       ksy[ 4] := casesy;
       ksy[ 5] := constsy;       ksy[ 6] := idiv;
       ksy[ 7] := dosy;          ksy[ 8] := downtosy;
       ksy[ 9] := elsesy;        ksy[10] := endsy;
       ksy[11] := forsy;         ksy[12] := functionsy;
       ksy[13] := ifsy;          ksy[14] := imod;
       ksy[15] := notsy;         ksy[16] := ofsy;
       ksy[17] := orsy;          ksy[18] := proceduresy;
       ksy[19] := programsy;     ksy[20] := recordsy;
       ksy[21] := repeatsy;      ksy[22] := thensy;
       ksy[23] := tosy;          ksy[24] := typesy;
       ksy[25] := untilsy;       ksy[26] := varsy;
       ksy[27] := whilesy;
       rewrite (paskey);
       write (paskey, key);
    
       ksy[ 1] := andsy;         ksy[ 2] := arraysy;
       ksy[ 3] := beginsy;       ksy[ 4] := casesy;
       ksy[ 5] := constsy;       ksy[ 6] := idiv;
       ksy[ 7] := dosy;          ksy[ 8] := downtosy;
       ksy[ 9] := elsesy;        ksy[10] := endsy;
       ksy[11] := forsy;         ksy[12] := functionsy;
       ksy[13] := ifsy;          ksy[14] := imod;
       ksy[15] := notsy;         ksy[16] := ofsy;
       ksy[17] := orsy;          ksy[18] := proceduresy;
       ksy[19] := programsy;     ksy[20] := recordsy;
       ksy[21] := repeatsy;      ksy[22] := thensy;
       ksy[23] := tosy;          ksy[24] := typesy;
       ksy[25] := untilsy;       ksy[26] := varsy;
       ksy[27] := whilesy;
       rewrite (pasksy);
       write (pasksy, ksy);
    
       sps['+'] := plus;         sps['-'] := minus;
       sps['*'] := times;        sps['/'] := rdiv;
       sps['('] := lparent;      sps[')'] := rparent;
       sps['='] := eql;          sps[','] := comma;
       sps['['] := lbrack;       sps[']'] := rbrack;
       sps['#'] := neq;          sps['&'] := andsy;
       sps[';'] := semicolon;
       rewrite (spsfile);
       write (spsfile, sps);
    
      rewrite (enterf);
      enter('          ', variable, notyp, 0);  (*sentinel*)
      enter('false     ', konstant, bools, 0);
      enter('true      ', konstant, bools, 1);
      enter('real      ', type1, reals, 1);
      enter('char      ', type1, chars, 1);
      enter('boolean   ', type1, bools, 1);
      enter('integer   ', type1, ints , 1);
      enter('abs       ', funktion, reals,0);
      enter('sqr       ', funktion, reals,2);
      enter('odd       ', funktion, bools,4);
      enter('chr       ', funktion, chars,5);
      enter('ord       ', funktion, ints, 6);
      enter('succ      ', funktion, chars,7);
      enter('pred      ', funktion, chars,8);
      enter('round     ', funktion, ints, 9);
      enter('trunc     ', funktion, ints, 10);
      enter('sin       ', funktion, reals, 11);
      enter('cos       ', funktion, reals, 12);
      enter('exp       ', funktion, reals, 13);
      enter('ln        ', funktion, reals, 14);
      enter('sqrt      ', funktion, reals, 15);
      enter('arctan    ', funktion, reals, 16);
      enter('eof       ', funktion, bools, 17);
      enter('eoln      ', funktion, bools, 18);
      enter('read      ', prozedure, notyp, 1);
      enter('readln    ', prozedure, notyp, 2);
      enter('write     ', prozedure, notyp, 3);
      enter('writeln   ', prozedure, notyp, 4);
      enter('          ', prozedure, notyp, 0);
    
      rewrite (symsetf);
      syset := [plus,minus,intcon,realcon,charcon,ident];
      write ( symsetf, syset );
      syset := [ident,arraysy,recordsy];
      write ( symsetf, syset );
      syset := [constsy,typesy,varsy,proceduresy,functionsy,beginsy];
      write ( symsetf, syset );
      syset := [intcon,realcon,charcon,ident,lparent,notsy];
      write ( symsetf, syset );
      syset := [beginsy,ifsy,whilesy,repeatsy,forsy,casesy];
      write ( symsetf, syset );
    
    end.
    


    Тут нужно пояснить, что директивы Dr. Pascal заключаются в фигурные скобки комментария и начинаются с символа «%». Директива {%O+} включает упрощенное наименование файлов, при котором, например, внешний файл, определенный как

    pasksy  : file of ksytype;

    так и будет называться «pasksy». Как и любой внешний файл, его надо указать в заголовке программы:

    program Pas1 (input,output,paskey,

    В оставшейся части PascalS также указываем файлы данных:

    {%D+}
    {%F- no reformatting }
    {%O+}
    program Pascals(input,output,paskey,pasksy,spsfile,enterf,symsetf);{1.6.75}
    

    Директива %D+ дает возможность программно остановить анимацию вызовом предопределенной процедуры Freeze.

    Тело программы PascalS будет выглядеть следующим образом:

    begin   {main program}
       assign (input,'QUEENS.PAS');
       reset  (input);
       init;
       block(blockbegsys+statbegsys, false, 1);
       finish;
    99: end.
    

    Где процедуры init и finish:
    procedure init;
    {%s-}
    
     var
      i : integer;
      EnterRec : EnterType;
    
    begin
     writeln;
     reset (paskey);   read  (paskey, key);
     reset (pasksy);   read  (pasksy, ksy);
     reset (spsfile);  read  (spsfile, sps);
     reset (symsetf);
     read  (symsetf,constbegsys,typebegsys,blockbegsys,facbegsys,statbegsys);
     stantyps := [notyp,ints,reals,bools,chars];
      lc := 0; ll := 0; cc := 0; ch := ' ';
      errpos := 0; errs := []; insymbol;
      t := -1; a := 0; b := 1; sx := 0; c2 := 0;
      display[0] := 1;
     iflag := false; oflag := false;
     if sy <> programsy then freeze{3} else
      begin insymbol;
       if sy <> ident then freeze{2} else
        begin progname := id; insymbol;
         if sy <> lparent then freeze{9} else
          repeat insymbol;
     if sy <> ident then freeze{2} else
     begin if id = 'input     ' then iflag := true else
           if id = 'output    ' then oflag := true else freeze{0};
       insymbol;
     end
          until sy <> comma;
          if sy = rparent then insymbol else freeze{4};
          if not oflag then freeze{20};
        end
      end ;
      reset (enterf);
      while not eof (enterf) do
       begin
        read  (enterf,EnterRec );
        with EnterRec do
         enter (fx0,fx1,fx2,fx3);
       end;
      with btab[1] do
        begin last := t; lastpar := 1; psize := 0; vsize := 0
        end ;
    end {init};
    
    procedure finish;
    {%s-}
    
     begin
      if sy <> period then freeze{22};
      {emit(31)};   {halt}
      if btab[2].vsize > stacksize then freeze{49};
     end {finish};
    


    Директива %s- отключает анимацию и показ значений переменных внутри процедуры, в которой она указана.

    Сделав указанные изменения, загрузил и выполнил первую часть (Pas1), а потом вторую. PascalS прочитал ферзей и приступил к их трансляции (см. картинку в начале). Следить за непрерывной анимацией такого большого кода, как PascalS, оказалось затруднительно, поэтому в ключевых точках вызвал freeze и пронумеровал вызовы в комментариях. Разобравшись в ситуации, продолжал анимацию командой Continue. Думаю, что в современных IDE современных языков подобные аниматоры были бы полезны.

    Описанные здесь «игры» делал давно на 286 CPU под MS DOS 3.2, сейчас только запустил старые файлы, чтобы сделать картинки. В заключение вспомнил интересный факт о распространении Dr. Pascal. Базовая поставка состояла из Руководства пользователя – книжка примерно 200 страниц на хорошей плотной бумаге и дискета. Стоила $99.95US и позиционировалась как low cost software. Лицензии на десятки рабочих мест в университетах стоили гораздо дешевле в пересчете на 1 копию. Но кроме Штатов и, нпр., Австралии, Dr. Pascal был популярен и в Индии. Насколько мне известно, местной компании была продана лицензия на распространение в Индии, и эта компания сама печатала книжки (тоже на английском 1:1 с оригиналом) и писала дискеты. Книжки были на газетной бумаге со слепым текстом, но цена была в пересчете с рупий около $4US. Та же компания тиражировала и другие популярные в то время продукты, типа LOTUS 1-2-3, dBase-4, ChiWriter и т.д. примерно за ту же цену.
    Поделиться публикацией

    Комментарии 33

      +1
      Всегда мечтал о чем-то подобном в современном мире. Но современном, допустимо не старше 15 лет. Начинал учиться на DOS-программах (на WinXP в эпоху без мобильного и местами без любого интернета) — TurboPascal была первой. Немного ностальгии.
      Современные экраны 1280х1024, 1366х768 и больше, на них можно отобразить больше информации, причем часть информации задать графически (что невозможно в текстовом режиме), часть информации открывать динамически — вкладки, спойлеры и другие способы узнать подробности.
      Жаль, что многие современные отладчики недалеко ушли от DOS-времен, это при условии если отладчик вообще запустится. Встречались даже отладчики для ЯП высокого уровня, которые предлагают отладку только для ассемблерного кода, т.е. логическую ошибку в них найти без знания ассемблера иной раз невозможно.
        +1
        Честно говоря не совсем понимаю зачем анимация могла бы пригодиться (ну, кроме обучения, естественно). Медитировать на то, как программа работает мне не кажется производительным занятием. Дебаг ведь начинается с построения гипотез. Имея гипотезы можно расставить брейкпойнты как можно ближе к потенциальным ошибкам и (если удача не подведет) этого будет достаточно.
        Проход по инструкциям делается только в достаточно узких местах между нормальным о ошибочным брейкпойнтом. И обычно там надо внимательно смотреть чего происходит. На неконтролируемой анимации можно легко чего-то пропустить.

        А фишки типа показа важных переменных в зависимости от контекста уже давно в современных IDE есть.
          0
          Имея гипотезы можно расставить брейкпойнты как можно ближе к потенциальным ошибкам и (если удача не подведет)
          Да, если удача не подведет. Иногда с анимацией бывает быстрее и баги найти, и просто в программе разобраться. См.:
          Laurie Tunniclife, Melbourne, Australia: «I am an electronics engineer who has been using Pascal professionally and privately for 15 years. I have been recently converting a 6000 line program to Extended Pascal and was having trouble with a part of the code.… I had spent quite a few hours on the problem with traditional debugging techniques which produced a confusing variety of runtime errors… Luckily I had a copy of Dr. Pascal which had an „Extended Pascal switch“ and could run the section of code that was crashing. It took all of 30 second to find the problems. One was my error, the other a compiler bug. Being able to see the variables displayed as I stepped execution of the code enabled me to locate the errors and fix them in record time. It's great to have a tool that supports Standard Pascal and Extended Pascal… From now on, I'll probably run new code on Dr. Pascal first and confirm it's working before adding it to a project.»
            0

            6 килолиний кода???
            Это или учебный проект или академический. Об этих случаях я не спорю — это другой мир.
            В продакшене это вообще ни о чем.

              0
              А что не так? 6К строк — слишком мало или слишком много?
                0

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

                  0
                  Наверное не стоит 100К строк в один файл впихивать? Лучше делать модули по несколько тысяч строк и отлаживать каждый отдельно.
                    0
                    Спасибо, Капитан Очевидность :-)
                    Конечно, даже за 6 KLOC неструктурированного кода надо приговаривать архитектора и/или ключевых разработчиков к смертной казни через «тумба-юмба».
                    Но это не отменяет того факта, что современные продукты содержат сотни тысяч строчек кода. И это задача разработчиков, архитекторов и прочих вовлеченных в деятельность, чтобы это все не привело к коллапсу продукта.
                    И да, это решается разделением одной большой хрени на множество иерархически (как правило) структурированных мелких хреней.

                    Но, если мы уж решили это так делить, то делать «атомарную» единицу в 6KLOC выглядит как-то… сомнительно, вам не кажется? Почему не разбить ее на 3 единицы в 2KLOC? А потом каждую на 1 KLOC? И так далее до некоторых величин, чтобы человек мог осознать эту величину просто на нее глядя на экране?
                    Где-то в 90-х вообще было мнение, что «процедура должна умещаться на одном экране» (напомню, размер экрана был 25 строк, приблизительно).

                    Просто надо понять, что то, что было круто 20 лет назад сейчас просто не работает.
                    — поменялись требования — программирование сейчас это не алгоритмы, как правило (академическую среду не рассматриваю, как я уже говорил).
                    — поменялись возможности — раньше считалось крутым писать «оптимальный код» (ну, там с учетом того, какая переменная пойдет в регистр, где inline функции лучше сделать и т. д.). Сейчас это весьма узкая специализация в embedded, и уже совсем не так выглядит, как раньше.
                    — поменялась инфраструктура программы. Раньше больше думали об алгоритмах (как я говорил), но совсем не думали о ресурсах. Сейчас больше думают о ресурсах. Уж если мы о Паскале — в Турбо Паскале моего детства sleep был реализован через цикл, который калибровался при старте программы. Сейчас за такое канделябром по голове дают.
                      0
                      Сейчас больше думают о ресурсах.

                      Уже в MacOS 7.0 (больше 20 лет назад) много думали о ресурсах. Что поделать — GUI.
                      поменялись возможности — раньше считалось крутым писать «оптимальный код»
                      ИМХО наоборот. Сейчас весь код почти оптимальный. Очень рано возникли правила, типа 1% кода жрет 99% времени, только его и надо оптимизировать. Оптимизировать приходилось руками. А сейчас современные компиляторы научились очень хорошо оптимизировать, отомизируют всё подряд, и, как правило, этого достаточно.
                      программирование сейчас это не алгоритмы
                      Не понял. Каждая программа это алгоритм + структуры данных.
                      А потом каждую на 1 KLOC? И так далее до некоторых величин, чтобы человек мог осознать эту величину просто на нее глядя на экране?
                      Чувство меры и здравый смысл никто не отменял.
                      Где-то в 90-х вообще было мнение, что «процедура должна умещаться на одном экране»
                      Для маленьких программ это и сейчас бывает разумно. Но и в старых программах этому не всегда следовали — см., нпр., процедуру init в статье. Как удобно — так и надо делать.
                      Сожалею, что приходится говорить очевидные, на мой взгляд, вещи :)
                        0
                        Уже в MacOS 7.0 (больше 20 лет назад) много думали о ресурсах. Что поделать — GUI.

                        Вы о каких ресурсах??? И при чем тут GUI?
                        Если что, я про ресурсы энергопотребления и тепловыделения, например. И они стали актуальными с появлением мощных процессоров и массовых автономных устройств. Есть и другие ресурсы, но эти наиболее очевидны)
                        А сейчас современные компиляторы научились очень хорошо оптимизировать, отомизируют всё подряд, и, как правило, этого достаточно.

                        Да, компиляторы оптимизируют. Поэтому никто не заморачивается писать «оптимальный» код (с современными архитектурами процессоров это даже несколько проблематично). Ровно то, что я сказал.
                        Не понял. Каждая программа это алгоритм + структуры данных.

                        Ну, если вы говорите об академической среде — возможно. Но современный программный продукт это еще и взаимодействие со внешними устройствами и сложной инфраструктурой за пределами программы.

                        Сожалею, что приходится говорить очевидные, на мой взгляд, вещи :)
                          0
                          Вы о каких ресурсах???

                          О, да. Забавная непонятка вышла. Я о Resource fork MacOS 7.0 и в виндах понятие «ресурс» есть. Ok. Разобрались:
                          Если что, я про ресурсы энергопотребления и тепловыделения, например.
                          Память — это ресурс? Если да, то раньше за каждый Кб боролись, что в ОЗУ, что на диске. А энергии в пересчете на 1 Кб та память жрала сильно больше, чем нынешняя. И стоила соответственно. И грелось это в пересчете на 1 Кб умопомрачительно.
                          Поэтому никто не заморачивается писать «оптимальный» код
                          Да. Т.е. крутизна оптимального кода осталась, но только она идет бесплатным приложением.
                          Но современный программный продукт это еще и взаимодействие со внешними устройствами и сложной инфраструктурой за пределами программы.
                          Современный программный продукт может моделировать новое лекарство или нефтяную скважину на суперкомпе, при этом кроме примитивного I/O ничего не иметь, даже подключения к инету. И потом: разве взаимодействие со внешними устройствами это не алгоритм? Одних инет протоколов многие тысячи.
                            0

                            Извините, но это звучит настолько дико, что я даже не знаю с какого конца комментировать.
                            Поверьте, современное построение программного продукта ушло значительно дальше Вирта.
                            Почитайте хоть Буча.
                            Мне кажется вы не занимаетесь производством ПО, верно? :)

                              0
                              Мне кажется вы не занимаетесь производством ПО, верно? :)
                              Вам кажется :)
                              Почитайте хоть Буча.

                              Он не сильно моложе Вирта ;)
                              Поверьте, современное построение программного продукта ушло значительно дальше Вирта.
                              Но сильно лучше не стало. Те же самые проблемы :( Нпр., только вчера
                                0
                                Хм… Вы парадигмы программирования оцениваете по возрасту тех, кто их продвигает в массы???
                                И почему вы приводите ссылку на проблему с unmanaged языками, в ответ на мой аргумент, что промышленная разработка ушла далеко???

                                Да, со времен Вирта появились новые парадигмы. Да, после С и C++ появились managed языки.
                                Нет, часть кода, всякие низкоуровневые вещи, алгоритмы, пишутся как раньше, и там есть проблемы 30-летней давности. Но «анимация в дебаге» где-то в стеке модема сотового телефона, поверьте, не поможет. Я знаю — я дебажил.
                                Возможно, ваша область производства ПО… ну, очень сильно отличается от того, с чем я знаком…
                                  0
                                  Вы парадигмы программирования оцениваете по возрасту тех, кто их продвигает в массы???

                                  Обычно нет, но в данном случае (м.б. мне показалось) Вы намекнули, что Вирт устарел. М.б. и Кнут устарел? ;)

                                  Да, со времен Вирта появились новые парадигмы. Да, после С и C++ появились managed языки.
                                  А «managed языки» это парадигма? Или я не понял — гугл отсылает на вики:
                                  Управля́емый код (англ. managed code) — термин, введённый фирмой Microsoft, для обозначения кода программы, исполняемой под «управлением» виртуальной машины .NET[
                                  Про .NET, конечно, разные мнения, но ИМХО не вижу, что это было революцией сравнимой со структурной, модульной и ОО. Поправьте, если ошибаюсь.
                                  Но «анимация в дебаге» где-то в стеке модема сотового телефона, поверьте, не поможет. Я знаю — я дебажил.
                                  Да. Вот мобильные устройства я не программировал. Поэтому полностью Вам верю. Телефон у меня самый простой и использую только чтобы СМС-пароли из банков получать (т.о. и как пользователю мне сказать тут нечего). А вот такой гаджет как электронная книга ИМХО явно и резко деградирует. Опасаюсь, что файлы скоро опять придется принтовать, как в конце 1990х.
                                  Возможно, ваша область производства ПО… ну, очень сильно отличается от того, с чем я знаком…
                                  Нпр., как сказал выше, моделирование новых лекарств.
              0
              Кстати, вчитался в цитату — похоже это многое объясняет:
              I am an electronics engineer who has been using Pascal professionally and privately for 15 years. I have been recently converting a 6000 line program to Extended Pascal and was having trouble with a part of the code


              Тут ни слова о профессиональном разработчике — чувак занимается электроникой, и, похоже, использовал программирование для каких-то вспомогательных задач (говно вопрос — не он первый, не он последний).
              Т.е. мы видим случай не профессиональной разработки, а именно случай обучения/академии.
                0
                Давно сложившаяся общемировая практика — одни учебные заведения выпускают универсальных программистов, другие — программистов, которые являются еще и спецами в определенной предметной области. Таких много, нпр., в квантовой механике, в экономике, в квантовой химии, в мат. химии и т.д. Инженер электроник и программист в одном лице может разрабатывать очень сложные профессиональные программы, нпр., по моделированию новых микропроцессоров. Такие программы, нпр., описаны в публикациях Интела.
              +1
              Анимация нужна, когда нет возможности остановить программу. Например, для программ управления какой либо промышленной установки.
                0

                Ну, это если только в очень узкой сфере, когда скорость исполнения должна быть достаточно быстрой для того, чтобы не получалось нажимать на step, но достаточно медленной, чтобы человек успевал понимать, что происходит.
                Как правило, если нельзя останавливаться, дебажутся по логам (хотя в моей практике были случаи, когда даже добавление логов меняло поведение из-за задержки)
                К тому же многие IDE позволяют условные бряки или выполнять действие на бряке, и продолжать выполнение после этого.

                  +1
                  В очень широкой области промышленной автоматики.
                  Суть в том, что программы выполняются циклически.

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

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

                      +1
                      Правда?

                      Окей — тебя будит электронный будильник, включаешь свет пультом, готовишь завтрак в микроволновке, выходишь из квартиры- автосвет в подъезде, садишься в лифт, заводишь машину, стоишь на светофоре, отмечаешься в метро и на входе в работу, включаешь кофеварку…

                      Оно просто работает, потому незаметно
                +1
                Может быть полезной для общего изучения программы, понимания куда она уходит при том или ином входе. Другими словами, можно сказать — для дебага ситуаций, когда информации для построения гипотез недостаточно, а проходить ручками тысячи шагов утомительно.
                  0

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

                    +1
                    Не путей, а шагов. Нажатий какой-нибудь F7 или что там у вас за Step Into отвечает в дебаггере. Десяток бряк расставлять по коду, который первый раз видишь — так себе идея, по-моему.
                      0
                      Десяток бряк расставлять по коду, который первый раз видишь — так себе идея, по-моему.

                      Почему???
                      Из описания баги понятны, как минимум, две точки для бряки, даже если вы код видите первый раз в жизни:
                      1. Там, где мы получаем данные (и было бы неплохо проверить, что они именно те, что надо).
                      2. Там, где мы получаем неверные данные (которые приводят к баге).

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

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

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

                      Метод половинного деления весьма эффективен, поверьте! Супротив пошаговому исполнению, лучше прям-таки на логарифм :)

                      З.Ы. а какой смысл жамкать F7 или запускать анимацию на коде, который вы не понимаете? По мне так это путь к беде — симптом, может быть, и поправите, но без осознания дизайна, весьма вероятно напортачите еще больше.
                        +1
                        Мы не знаем где получаем данные и мы не знаем где получаем неверные данные (процесс крашится, например).

                        И что вы будете делать, если вроде знаете, поставил две бряки, а они не срабатывают?
                          0

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

                        0
                        Да, кстати, минутка математики — 1000 шагов в анимации в 1 секунду это более 15 минут.
                        Поддерживать внимание каждую секунду над непонятным процессом в течении 15 минут… Ну, возможно, кто-то это может, но Супермен, КМК, может и сам реализовать подобную опцию в IDE, если захочет.
                          0
                          Я читал Вирта, в частности, о его подходе к построению компиляторов. Т.о. в общем мне было понятно устройство PascalS, но не отдельные детали. Анимацию я крутил около часа, то ускоряя, то замедляя, а то и останавливая. И у меня нет впечатления, что я даром потратил этот час. Усталость не больше, чем от внимательного просмотра кинофильма.
                            0

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

                              0
                              Я сомневаюсь в полезности при разработке современного продакшен кода.
                              Я с этим не спорю — имеете полное право сомневаться. Есть очень разные задачи и очень разные подходы к их решению. Если в поставке современной IDE будет опция анимации, то ИМХО сильно не утяжелит, но всякий сможет попробовать на своей задаче. Если почти никому не понравится — не проблема: мало ли всяких бесполезных штучек добавляют в очередную версию (а тут хотя бы для обучения подойдет :)

                              Про «17 лет работы» (у меня больше) — мода живет меньше — отвыкайте от привычки следовать моде (я про это писал).
                  0
                  Bret Victor делает очень крутые инструменты по очеловечиванию процесса отладки:
                  www.youtube.com/watch?v=PUv66718DII

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

                  Самое читаемое