3 ms·
My canonical use-case for macros in Scheme is writing unit tests. If you want to see the unevaluated expression that caused the test failure, you'll need a macr
by hellcow 2y ago
My canonical use-case for macros in Scheme is writing unit tests. If you want to see the unevaluated expression that caused the test failure, you'll need a macro.
(define-syntax test (syntax-rules ()
((_ test-expr expected-expr)
(let ((tv (call-with-values (lambda () test-expr) list))
(ev (call-with-values (lambda () expected-expr) list)))
(if (not (equal? tv ev))
(printf
"\nTest failed: ~s\nWanted: ~s\nGot: ~s\n"
'test-expr
ev
tv)))))))
- zelphirkalt 2y agoI've got another similar use-case: Function contracts. There you also probably want to see the unevaluated form of the assertion on failure.
- neilv 2y agoAlso, with `syntax-case` or `syntax-parse`, you can have the IDE know the syntax for the test case that failed: https://www.neilvandyke.org/racket/overeasy/ https://www.neilvandyke.org/racket/overeasy/
- _dain_ 2y agoPython's pytest framework achieves this without macros. As I understand it, it disassembles the test function bytecode and inspects the AST nodes that have assertions in them.
- zelphirkalt 2y agoInspecting the AST ... That kind of sounds like what macros do. Just that pytest is probably forced to do it in way less elegant ways, due to not having a macro system. I mean, if it has to disassemble things, then it has already lost, basically, considering how much its introspection is lauded sometimes.