В процессе переписывания моей программки с хаскеля на OCaml, обнаружилась замечательная фича окемловского отладчика, выглядит примерно так:
Причем оно реально работает. Даже в случае когда, например, читаем из файла массив — после stepback/step forward функция чтения прочитывает то же самое значение.
За это я даже готов простить окемлу использование big-endian в самых неожиданных местах и то что там == используется для сравнения physical equality (сравнение указателей, проще говоря, если x == 0.0 и y == 0.0 то (x == y) вернет false).
Путем недолгих поисков в гугле обнаружилось что это также называется красивым словосочетанием omniscient debugging, статья о том как это работает, а также replay debugger для java, позволяющий даже многопоточные приложения отлаживать в обе стороны.
Вещь просто суперудобная, хотя, понятно, в некоторых случаях она работать не будет. Если ваша программа, скажем, запускает баллистическую ракету, то stepback после выполнения функции launch() реализовать трудновато. Тем не менее всякие алгоритмы с минимумом side-эффектов отлаживать таким образом одно удовольствие :)
Ссылки:
- Bil Lewis, "Debugging Backwards In Time" — дядька с replay debugger'ом для явы; есть еще запись его лекции, очень смешной чувак, рассказывает в ковбойской шляпе и использует игрушечных змей для иллюстрации;
- A. Tolmach, A. Appel "A Debugger for Standard ML" — собственно про replay дебаггер для ML;
- M. Ronsse, K. De Bosschere, J. De Kergommeaux "Execution Replay and Debugging" — еще неплохая статья, затрагивает также отладку параллельных и распределенных приложений.
9 comments:
Да, ocamldebug - штука замечательная.
С оператором (=) ошибочка вышла - он проверяет на структурное равенство. Физическое равенство - это (==), причем для целых чисел между физическим и структурным равенством разницы нет.
# let x=0 and y=0 in x=y;;
- : bool = true
# let x=0 and y=0 in x==y;;
- : bool = true
# let x=0 and y=2-2 in x==y;;
- : bool = true
# let x=[] and y=[] in x=y;;
- : bool = true
# let x=[] and y=[] in x==y;;
- : bool = true
# let x=[1] and y=[1] in x==y;;
- : bool = false
Ты всё-таки крайне ценный кадр (:
Да, точно, с оператором (=) напутал. Исключительно потому что он выел мой непривыкший к окемлу мозг ;) Щас поправлю..
Самое забавное, что в большинстве случаев окемловский дебагер нафиг не нужен. Программы не падают из-за неправильного доступа к памяти и не совершают тупых ошибок, ибо типизация. Все остальное можно протестить интерактивно (Ctrl-Alt-X - самое любимое сочетание в емаксе) или парочкой осмысленных Printf-ов.
У кемла еще очень прикольная объектная система. Но она тоже нафиг не нужна :), ибо почти всегда есть более подходящие абстракции.
А из-за чего прога переписывается на кемл - любопытство или чем-то не устраивает хаскел?
Отчасти любопытство, да.
Основная причина это стремление получить что-то работающее правильно и быстро за пару недель максимум.
Прога это диплом мой, на самом деле, а защита через полтора месяца :)
Хаскел устраивает почти всем, в окемле сильно недостает list comprehensions. А в хаскеле более удобных mutable массивов и быстрых функций для I/O этих самых массивов.
В общем я пока решил это на окемле писать, а имеющуюся хаскелевскую отлаженную версию использовать как прототип.
А что хоть прога то делает. Зачем там столько массивов и list comprehensions?
Прога картинки сжимает, поэтому там очень много массивов. Точнее массив один но очень большой.
А списки там в алгоритме самом широко используются. Без list comprehensions я могу жить конечно, но с ними красивее :)
По хорошему это конечно задачка для С - врядли кто умеет работать с массивами лучше (по части производительности). Да и битовые операции там наиболее прямые.
Хотя в кемле тоже не шибко удобно работать с массивами - текст может хуже сишного получиться (особенно, если куча floating point операций), но сделать какой-нибудь замудреный алгоритм на нем все же проще.
Есть еще куча языков и сред, у которых с массивами вроде как легче: какие-нибудь потомки APL :) Или всякие matlab, mathematica, octave. Возможно какой-то прототип можно и на них наклепать.
Ну понятно что по-человечески это проще и быстрее сделать на MATLAB/C++. Большая часть того что я писал (из области обработки изображений) так и работает. Но это было бы неинтересно :)
А какой-нибудь диалект APL был бы действительно идеальный вариант, но экспириенса с ним пока маловато-таки у меня..
Post a Comment