Обработка ошибок

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

(nil  try (nil  eval  task)
  out-of-memory (cout writeln "Out of memory")
  nil (cout writeln "Task " task  " is wrong"))

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

(nil  try (nil  eval  task)
  nil (cout writeln "Exception is " (nil  exception)))

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

('vector  defmethod add-number  (x  n)
  (nil  if  (nil  numberp x)
    (nil  if  (nil  numberp n)
      (nil  try (this push  x n)
        nil (nil  throw 'out-of-memory))
      (nil  throw 'syntax))
    (nil  throw 'syntax)))
(nil  setq  v ('vector  newobject))
(nil  try (v  add-number  "1")
  nil (cout writeln "error: " (nil  exception)))
(nil  try (v  add-number  1 1e10)
  nil (cout writeln "error: " (nil  exception)))

  Результатом будет выводы ошибок syntax и out-of-memory.

  Самым важным моментом отладки программ является вывод истории вычислений, в момент когда исключение возникло. Историю можно получить с помощью функции (nil exception-history). История задаётся как список (… (integer-number-глубина-вычислений-в-стеке bool-вход/выход команда) …). Для просмотра можно вызвать функцию (stream history-show (nil exception-history)).

  Предположим у вас рушится простая функция для доступа к элементам вектора.

('vector  defmethod element (i)
  (nil  if  (nil  and (i  >=  0)  (i  <	(this	size)))
		(this	elt	i)))

  После тщетных попыток отладить программу вы напишите вывод истории вычислений.

(nil  try
  (vector element i)
  nil
  (cout history-show  (nil  exception-history)))

  Результат вывода истории всегда впечатляет.

 inp< (this elt i)
 inp< this
 out> #(a b c)
 inp< (#(a b c) elt i)
 inp< (#(a b c) BIM(vector,elt) i)
  inp< i
  out> 2.5
 inp< (#(a b c) BIM(vector,elt) 2.5)
 out> nil
 out> nil
 out> nil