Шаг 101.
Общие сведения по отладке программ

    На этом шаге мы приведем некоторые общие сведения по отладке программ.

    Приведем несколько тестовых примеров для нашего интерпретатора: они, к сожалению (!), не позволили найти ошибки:

   1. <-- ((NLAMBDA1 (X) (CDR1 X)) (1 (TIMES1 1 2) 4))
      --> ((TIMES1 1 2) 4)
      <-- ((NLAMBDA1 (X) (CAR1 X)) ((TIMES1 1 2) (PLUS1 1 4)))
      --> (TIMES 1 2)
   2. <-- (DEFUN1 SUMMA (LAMBDA1 (LST) (COND1 ((EQUAL1 LST
      NIL1) 0) (T1 (PLUS1 (CAR1 LST) (SUMMA (CDR1 LST))))))
      --> (LAMBDA1 (LST) (COND1 ((EQUAL1 LST NIL1) 0) (T1
      (PLUS1 (CAR1 LST) (SUMMA (CDR1 LST)))))
      <-- (SUMMA (QUOTE1 (1 2 3)))
      --> 6
   3. <-- (DEFUN1 FACT (LAMBDA1 (X) (COND1 ((EQUAL1 X 1) 1)
      (T1 (TIMES1 X (FACT (DIFFERENCE1 X 1)))))))
      --> (LAMBDA1 (X) (COND1 ((EQUAL1 X 1) 1) (T1 (TIMES1
      X (FACT (DIFFERENCE1 X 1))))))
      <-- (FACT 5)
      --> 120
   4. <-- (DEFUN1 TEST (LAMBDA1 (X Y) (CONS1 X Y)))
      --> (LAMBDA1 (X Y) (CONS1 X Y))
      <-- (TEST A B)
      --> (A . B)
   5. <-- (DEFUN1 COPY (LAMBDA1 (E) (COND1 ((ATOM1 E) E) (T1
      (CONS1 (COPY (CAR1 E)) (COPY (CDR1 E)))))))
      --> (LAMBDA1 (E) (COND1 ((ATOM1 E) E) (T (CONS1 (COPY
      (CAR1 E)) (COPY (CDR1 E))))))
      <-- (COPY (QUOTE1 (A B C)))
      --> (A B C)
   6. <-- (DEFMACRO1 AAA (NLAMBDA1 (G) (CAR1 G)))
      --> (NLAMBDA1 (G) (CAR1 G))
      <-- (AAA ((TIMES1 2 3) 4 5))
      --> (TIMES1 2 3)
Далее можно все более и более расширять возможности построенного интерпретатора, пользуясь собственным механизмом определения функций.

    Например, определим функцию NULL1 через примитивы системы:

   <-- (DEFUN1 NULL1 (LAMBDA1 (L) (EQUAL1 L NIL1)))
   --> (LAMBDA1 (L) (EQUAL1 L NIL1))
и сразу же воспользуемся ею:
   7. <-- (DEFUN1 MEMBER1 (LAMBDA1 (AL LST) (COND1 ((NULL1
      LST) NIL1) ((EQUAL1 AL (CAR1 LST)) LST) (T1 (MEMBER1
      AL (CDR1 LST))))))
      -->  (LAMBDA1 (AL LST) (COND1 ((NULL1 LST) NIL1)
      ((EQUAL1 AL (CAR1 LST)) LST) (T1 (MEMBER1 AL (CDR1
      LST)))))
      <-- (MEMBER1 (QUOTE1 B) (QUOTE1 (A B C)))
      --> (B C)
   8. <-- (DEFUN1 DEL (LAMBDA1 (A L) (COND1 ((NULL1 L) NIL1)
      ((EQUAL1 (CAR1 L) A) (CDR1 L)) (T1 (CONS1 (CAR1 L)
      (DEL A (CDR1 L)))))))
      --> (LAMBDA1 (A L) (COND1 ((NULL1 L) NIL1) ((EQUAL1
      (CAR1 L) A) (CDR1 L)) (T1 (CONS1 (CAR1 L) (DEL A (CDR1
      L)))))
      <-- (DEL 5 (QUOTE1 (3 4 5)))
      --> (3 4)
   9. <-- (DEFUN1 EVERY (LAMBDA1 (L) (COND1 ((NULL1 L) NIL1)
      ((NULL1 (CDR1 L)) L) (T1 (CONS1 (CAR1 L) (EVERY (CDR1
      (CDR1 L))))))))
      --> (LAMBDA1 (L) (COND1 ((NULL1 L) NIL1) ((NULL1 (CDR1
      L)) L) (T1 (CONS1 (CAR1 L) (EVERY (CDR1 (CDR1 L)))))))
      <-- (EVERY (QUOTE1 (A P R O L D)))
      (A R L)
  10. <-- (DEFUN1 APPEND1 (LAMBDA1 (L1 L2) (COND1 ((NULL1 L1)
      L2) ( T1 (CONS1 (CAR1 L1) (APPEND1 (CDR1 L1) L2)))))))
      --> (LAMBDA1 (L1 L2) (COND1 ((NULL1 L1) L2)  (T1 (CONS1
      (CAR1 L1) (APPEND1 (CDR1 L1) L2))))))
      <-- (APPEND1 (QUOTE1 (A P R)) (QUOTE1 (O L D)))
      (A P R O L D)

    После проверки Вас может заинтересовать три вопроса:

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

    На первые два вопроса мы ответим ниже (см. более подробное изложение в [1]).

    Будем говорить, что "в программе имеется ошибка, если ее выполнение не оправдывает ожиданий пользователя" [2, 3].

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

    Составные части процесса отладки можно схематически изобразить в "форме Бэкуса-Наура":


                         ¦  Процесс  ¦ ¦   Процесс   ¦
  [Процесс отладки] ::=  ¦   поиска  ¦ ¦ исправления ¦
                         ¦   ошибки  ¦ ¦   ошибки    ¦
                         
       ¦  Процесс ¦     ¦   Процесс    ¦ ¦   Процесс   ¦
       ¦  поиска  ¦ ::= ¦ тестирования ¦ ¦ локализации ¦
       ¦  ошибки  ¦     ¦  программы   ¦ ¦   ошибки    ¦

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

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

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

    Более подробную информацию по отладке программ можно получить в разделе "Отладка".

    Со следующего шага мы начнем рассматривать связь языка программирования LISP с другими языками.




Предыдущий шаг Содержание Следующий шаг