On Saturday, July 16, 2016 at 7:06:10 PM UTC-4, David K. Storrs wrote: > So, if one should prefer functions, what is a good place to use > macros? When people talk about why LISP/Scheme/Racket are the most > powerful languages, they inevitably mention macros and continuations. > What is a good use case for macros?
You generally want macros for things that can't be done with functions period, for instance a static type checker, pattern matching, a class system with static method resolution, making your own language, etc. Your use case can benefit from macros by having a function that accepts a procedure to test and making a macro that constructs the function from a series of body expressions. Consider an example of a slightly modified version of your throws function: (throws "Should throw when frobnicating non-widgets" exn:fail:contract? (lambda () (frobnicate (make-gizmo)))) Notice you have to wrap the "(frobnicate (make-gizmo))" expression in a thunk (a function that takes no arguments) so the throws function can control when the test expression is evaluated. If you didn't, throws would evaluate "(frobnicate (make-gizmo))" as its argument before doing anything and the exception would be thrown immediately. If you don't want to have to write the wrapper lambda all the time, you can make a macro version of throws that adds the lambda for you: ; define-simple-macro is basically define-syntax-rule but using syntax-parse ; instead of syntax-case (define-simple-macro (throws-macro message:expr matcher:expr body:expr ...+) (throws message matcher (lambda () body ...))) ; expands to a call to the throws test function (throws-macro "Should throw when frobnicating non-widgets" exn:fail:contract? (frobnicate (make-gizmo))) The throws-macro *at compile time* transforms the body expression it's given into an expression with a wrapper lambda, but *at runtime* the throws function does all the actual testing and logic. It's common for macro-writers to keep as much logic as possible out of macros and in runtime functions, as that's what functions are best at. One last note - this particular use case for macros can also be achieved with lazy evaluation, but macros and lazy evaluation in general have very different non-overlapping goals and it's best not to conflate them. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.