Каковы эффективные способы отладки Common Lisp в Emacs и SLIME?

Мне интересно, каковы некоторые эффективные способы интерактивной отладки Common Lisp с использованием Emacs и SLIME.

Что я делал раньше: как человек, который изучил C и Python, используя IDE (VS и PyCharm), я привык устанавливать точки останова, добавлять часы и делать шаги. Но когда я начал использовать CL, я обнаружил, что процесс отладки принципиально отличается. Я не нашел хороших способов установить точки останова, пройтись по линиям и посмотреть, как меняются переменные.

Глупый метод, который я использовал, заключался в добавлении "print" в код и повторном запуске кода, что очень неэффективно. Я знаю, что мы можем "проверять" переменные в SLIME, но не уверен, как это сделать в интерактивном режиме.

Что я нашел: я недавно наткнулся на это видео о разработке переводчика азбуки Морзе, и оно показывает полный процесс интерактивной отладки в SLIME, который был очень информативным и поучительным. Это как если бы мы могли "поговорить" с компилятором.

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

  • Как отлаживать в интерактивном режиме?
  • Каковы некоторые хорошие практики и советы? Как добавить точку останова и шаг?
  • Какие ярлыки/инструменты/рабочий процесс вы используете чаще всего/считаете наиболее полезными при отладке?

Ответ 1

Есть много вещей, которые вы можете сделать:

  • Вы можете проследить вызов функции (см. TRACE и UNTRACE в Common Lisp или slime-toggle-trace-fdefinition*). Это помогает с рекурсивными вызовами: вы можете видеть, что вы передаете, и то, что они возвращают на каждом уровне.
  • Стандартная вещь: добавьте (format t ...) в места. Думаю, нет необходимости комментировать.
  • Если код сломается, вы попадете в отладчик. Оттуда вы можете проверить стек, посмотреть, что было вызвано и какие аргументы были переданы. См. Ссылку @jkiiski: у нее есть действительно отличная информация об этом, включая форму (break), которая будет действовать как точка останова и приведет вас к отладчику. Предупреждение о spoiler: вы можете изменить значения в инспекторе, вы можете изменить и повторно скомпилировать свой код и перезапустить (почти) любое место в стеке.
  • И последнее, но не менее важное: для отладки макросов вам понадобится slime-macroexpand-1 (обертка поверх MACROEXPAND-1) и даже лучше C-c M-e для макро шага.

Последний совет: если вы хотите провести серьезную отладку, включите (declaim (optimize (debug 3))) в свой файл, в противном случае некоторые реализации CL имеют тенденцию оптимизировать вызовы в стеке или сделать недопустимыми аргументы.

Ответ 2

С помощью Common Lisp и Slime вы можете устанавливать точки останова, просматривать значения переменных, использовать инспектор для просмотра составных структур данных, включая экземпляры классов, и пошагово просматривать код - все в принципе довольно похоже на то, что вы используете в IDE. как PyCharm. Видео Rainer Joswig Отладка CL-HTTP с использованием Clozure Common Lisp, GNU Emacs и SLIME (https://vimeo.com/77004324) демонстрирует все эти функции, поэтому вы можете увидеть, как это делается на практике с Slime.

Одна особенность, которую я на самом деле предпочитаю в Common Lisp + Slime, чем отладка с помощью PyCharm, заключается в том, что в первом случае вы можете запускать свою программу в обычном режиме и автоматически запускать отладчик непосредственно при ошибке, и отладчик по умолчанию останавливается там, где возникло необработанное исключение. В отличие от этого, с PyCharm вы запускаете свою программу, сталкиваетесь с ошибкой, затем снова запускаете программу с помощью отладчика и вручную устанавливаете свои точки останова или просите PyCharm прервать работу при любом исключении. PyCharm в настоящее время не поддерживает автоматическое прерывание только при необработанном исключении.