Как упражнение в изучении макросистемы Racket, я реализовал единую систему тестирования, основанную на C++ catch framework. Одной из особенностей этой структуры является то, что если я пишу чек так:Macro для записи шагов оценки и промежуточных значений в Racket?
CHECK(x == y); // (check x y)
Когда проверка нарушается сообщение об ошибке будет распечатать значения х и у, даже если макрос используется полностью универсален , в отличие от других тестовых фреймворков, которые требуют использования макросов, таких как CHECK_EQUALS, CHECK_GREATER и т. д. Это возможно благодаря хакерству, включающему шаблоны экспрессии и перегрузку оператора.
Мне приходит в голову, что в Racket вы сможете сделать еще лучшую работу. В версии C++ макрос не может видеть внутри подвыражения, так что если вы пишете что-то вроде:
CHECK(f(x, g(y)) == z); // (check (= (f x (g y)) z))
Когда проверка нарушается вы только выяснить значения левой и правой стороны от знака равенства, а не значения x, y или g (y). В ракетке я ожидаю, что можно будет переписать в подвыражения и напечатать дерево, показывающее каждый шаг оценки.
Проблема Я понятия не имею, что лучший способ сделать это:
- Я получил довольно знакомы с синтаксисом-синтаксического анализа, но это, кажется, за пределами его возможностей.
- Я читал о настройке приложения #%, которое почти похоже на то, что я хочу, но если, например, f является макросом, я не хочу печатать каждую оценку выражений, находящихся в расширении, просто оценки выражения, которые были видны, когда пользователь вызывал макрос проверки. Также не уверен, могу ли я использовать его без определения языка.
- Я мог бы использовать параметр синтаксиса для захвата смысла основных операторов, но это не поможет с вызовами функций, такими как g (y).
- Я мог бы использовать синтаксис-> datum и вручную ходить по AST, вызывая eval на подвыражения сам. Это кажется сложным.
- Библиотека трассировки почти похожа на то, что она делает то, что я хочу, но вы должны дать ей список функций заранее, и она, похоже, не дает вам никакого контроля над тем, куда идет вывод (я хочу только распечатать ничего, если проверка завершится неудачей, а не если она преуспеет, поэтому мне нужно сохранить промежуточные значения в сторону по мере продолжения выполнения).
Что было бы лучшим или по крайней мере идиоматическим способом реализации этого?
бы кто голосовал, чтобы закрыть разум, объясняя, почему? вопрос довольно конкретный, я не уверен, как его можно интерпретировать как «широкий», –