Подскажите, как отлаживать код на лиспе. Никак не могу найти края, за который можно было бы распутать ошибку.
Вот код, где точно ошибка:
(defclass kd-node ()
((split-position :initarg :split
:initform 0.0
:accessor :split
:type coordinate))
((left :initarg :left
:accessor :left))
((right :initarg :right
:accessor :right))
(:documentation "If both branches are available, it is a node. If a the LEFT has something and the RIGHT is nil, it is a leaf and the LEFT has the contents of the leaf."))Мне говорит такое:
keyword argument not a symbol:
(LSRT-TYPES::LEFT :INITARG :LEFT :ACCESSOR :LEFT).
[Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]
Restarts:
// выбросил для экономии места
Backtrace:
0: (SB-PCL::CHECK-APPLICABLE-KEYWORDS 0 T 571809 18)
1: ((LAMBDA (SB-PCL::.PV. SB-PCL::.NEXT-METHOD-CALL. SB-PCL::.ARG0. SB-PCL::.ARG1. SB-INT:&MORE SB-PCL::.DFUN-MORE-CONTEXT. SB-PCL::.DFUN-MORE-COUNT.)) ..)
2: (SB-MOP:ENSURE-CLASS LSRT-TYPES::KD-NODE)[:EXTERNAL]
3: (SB-PCL::REAL-LOAD-DEFCLASS ..)
4: ((SB-C::TOP-LEVEL-FORM ..))[:TOPLEVEL]
5: (SB-FASL::LOAD-FASL-GROUP #<SB-SYS:FD-STREAM for "file d:\\Paul.revised\\git.repos\\github\\lsrt-types\\sbcl-1.0.37-win32-x86\\lsrt-types.fasl" {24984C71}>)
6: ((FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK))
и так далееПодскажите, как можно определить место ошибки? Дебаггер никак не помогает в этом: нет ни ссылок на нескомпилировавшиеся sexp-ы, ни точек в тексте, где что-то пошло не так. Просто, "файл не скомпилировался" и описание ошибки.
Если нужен код файла, то я дам отдельно, чтоб в топике не засорять.
слишком много сkобок и кивордов ;)
Здесь исправлено:
(defclass kd-node ()
((split-position :initarg :split
:initform 0.0
:accessor split
:type coordinate)
(left :initarg :left
:accessor left)
(right :initarg :right
:accessor right))
(:documentation "If both branches are available, it is a node. If a the LEFT has something and the RIGHT is nil, it is a leaf and the LEFT has the contents of the leaf."))
синтаксис defclass такой:
(defclass name (superclass*) (slot*) option*)
то есть, все слоты должны быть во вторых скобках, а не каждый в отдельной паре
кроме того, :accessor, по-хорошему, должен быть обычным символом, а не ключевым.:accessor вводит именованную функцию, с соответствующим именем
ааа блин, точно! отступы не помогли, а я на них полагаюсь...
Да, по конкретной ошибке я понял.
Подскажите, как можно дебажить загружаемый код? В данном случае я знал, где ошибка и это большая помощь, но в общем случае - это жесть, комментировать куски кода и смотреть, изменяются ли сообщения об ошибках. (Это самый простой вариант, который я нашёл).
> Подскажите, как можно дебажить загружаемый код? В данном случае я знал, где ошибка и это большая помощь, но в общем случае - это жесть,> комментировать куски кода и смотреть, изменяются ли сообщения об ошибках. (Это самый простой вариант, который я нашёл)http://lisper.ru/articles/sbcl-debuggingА вапще с опытом должно появиться умение представлять источник ошибки сразу по сообщению отладчика в несложных случаях.
жесть:
Обратная трассировка (backtrace) в SBCL на настоящий момент реализована не лучшим образом, не придавайте ей много значения. Просто загляните (вызовите любую ошибку) в REPL и выясните, что происходит. Поразвлекайтесь с штатным отладчиком SBCL и модным Slime Debugger, прежде чем будете пользоваться ими на практике, и тогда они перестанут казаться вам враждебными. О том, как пользоваться обратной трассировкой, я напишу в другой раз.
Это основной механизм, который я использовал в С-подобных и который я пытался применить здесь...
> Обратная трассировка (backtrace) в SBCL на настоящий момент реализована не лучшим образом, не придавайте ей много значения
Нагло врут. Вполнне нормальная она, и с SLIME интегрируется нормально. Если компилировать с (debug 3) - так вообще всё замечательно.
> Нагло врутДумаю, человеку с именем Nikodemus Siivola в этом вопросе стои верить :)
Вероятно, он считает, что она могла быть сделана гораздо лучше.
Хотя ее ценность в лиспе, вообще говоря, сомнительна
> Думаю, человеку с именем Nikodemus Siivola в этом вопросе стои верить :)
Сейчас посмотрел оригинал - блин, и кто это переводил? Фразу "While SBCL backtraces aren't at the moment the pretties ones in the world, try to make sense out of them" можно перевести как "Хотя SBCL сейчас выдаёт обратную трассировку не в самом лучшем виде, постарайтесь всё же с ней разобраться". Но никак не так, как написано в русском переводе.
Доделывать там, наверное, есть что, но оно вполне годное и довольно удобное (не хуже (даже лучше во многом) чем backtrace в том же gdb).
> Сейчас посмотрел оригинал - блин, и кто это переводил?
Ну, дык, ссылка там есть же ) Вообще, если есть возможность проверить перевод - то было бы здорово. Например, можно сейчас на wiki выложить "правильный", а я бы потом перенёс его в статьи.
> Хотя ее ценность в лиспе, вообще говоря, сомнительна
Почему это? Я в лиспворксе частенько не только бэктрейс смотрю, но ещё и по стеку вверху-вниз хожу.
В сиплюсплюсовом STL есть проблемы с выводом ошибок компиляции шаблонов. А именно - иногда компилятор вываливает много экранов логов простой ошибки, где невероятно сложно найти корень этой самой ошибки.
Так к чему я это: для конкретно этой проблемы было найдено решение в виде отдельной программы, которая эти логи ошибок анализирует и выдаёт их в удобочитаемом виде, выбрасывая внутренние, ненужные пользователю, промежуточные элементы.
Вопрос такой: а для SBCL есть что-то подобное, что извлекало бы из бэктрэйса только код пользователя, выкидывая кишки компилятора? Или это в принципе нерешаемая задача?
По бектрейсу смотреть надо.Вот конкретно тут все понятно даже без кода:
Лисп-система вычисляет что-то в REPL:
4: ((SB-C::TOP-LEVEL-FORM ..))[:TOPLEVEL]
Парсинг макроса DEFCLASS:
3: (SB-PCL::REAL-LOAD-DEFCLASS ..)
ENSURE-CLASS это функция из метаобъектного протокола,
в которую раскрывается DEFCLASS:
2: (SB-MOP:ENSURE-CLASS LSRT-TYPES::KD-NODE)[:EXTERNAL]
Вызов метода этой обобщенной функции:
1: ((LAMBDA (SB-PCL::.PV. SB-PCL::.NEXT-METHOD-CALL. ..) ..)
Метод обломался, так как принял ((left )) за option defclass'а.
В опциях всегда первым аргументом должен идти keyword-символ, а тут - список.
0: (SB-PCL::CHECK-APPLICABLE-KEYWORDS 0 T 571809 18)
keyword argument not a symbol:
(LSRT-TYPES::LEFT :INITARG :LEFT :ACCESSOR :LEFT).
[Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]
Пакет SB-PCL по-хорошему давно надо переименовать в SB-CLOS.
PCL расшифровывается как Portable Common Loops - это предок CLOS, объектной системы CL. Название еще из CMUCL осталось, с тех пор, как тот был еще даже не CL, а Spice Lisp
А что такое "код пользователя"? Функции? Функции он отлично показывает.Ошибки в стандартных макросах и функциях тоже понятны, в принципе.
А макросы из third-party библиотек это уже проблема не самого SBCL.
Ошибки в крестовых темплейтах более детерминированы, чем ошибки в S-выражениях. Что вот должен выдавать сторонний тулз на ошибку в программе на DSL, про который он ничего не знает и знать не может?
> Сейчас посмотрел оригинал - блин, и кто это переводил?Я переводил. Как перевел, так оставил без изменения, вроде никто не захотел пробежаться по исходнику.
Спасибо за замечание, сегодня исправлю и заодно пройдусь по остальному тексту.
> Почему это? Я в лиспворксе частенько не только бэктрейс смотрю, но ещё и по стеку вверху-вниз хожу.
Круто.
Но имхо отладочная печать в cl более полезна и удобна.
> Но имхо отладочная печать в cl более полезна и удобна.
Вот я тоже на этом варианте пока что остановился. Не могу я запросто продраться через CLOS и подробности SBCL не имея понятия об их внутренностях.
Кстати, о внутренностях. Love5an, подскажи пожалуйста, откуда у тебя информация о семантике вызовов? Я вот почитал Соню Киин, у неё подробностей о MOPе нет. Есть только описание некоторых особенностей CLOS. Есть что-то об CLOS или SBCL в удобоваримой форме, кроме самих исходников?
>Кстати, о внутренностях. Love5an, подскажи пожалуйста, откуда у тебя информация о семантике вызовов? Я вот почитал Соню Киин, у неё подробностей о MOPе нет. Есть только описание некоторых особенностей CLOS. Есть что-то об CLOS или SBCL в удобоваримой форме, кроме самих исходников?
AMOP. Плюс, вот тут вот можно почитать: http://lisp.org/mop/index.html ИМХО здесь всё проще и понятнее. А главное на примере: http://infolab.stanford.edu/~paepcke/shared-documents/mopintro.ps
"it should come with a warning though - You might get an uncontrollable urge to make an ORM" (c) p_l