reddit / emacs

Pattern matching macros vs functions?

cuntymccuntlicker · 2022-11-29 04:19
As an exercise in learning Lisp, I am trying to write a pattern matching routine that I can call like `(match pattern form)` where both pattern and form are just forms. My ultimate goal is to perform tree-manipulations via structural editing and macroexpansion of lisp forms, where after the manipulation, I am left with a lisp form that evaluates to something useful. Because working with code is a macro's domain, I thought using them would be the most natural way forward. However, due to the recursive nature of the problem, I need to call `match` from within itself to see if a sub-pattern successfully matched a sub-form. This leads to write things like `(eval \`(match\` `,sub-pattern ,sub-form))` inside the macro. This feels like an ugly hack, but the alternative would be to use functions and quote every input, leading to `(match \`(quote ,sub-pattern) \`(quote\` `,sub-form))` . Both of these make me feel like I am doing something wrong, surely there is a clean, lispy way of doing this. Is there an idiomatic way to write the routine? Should this be a task for functions or macros?
agrostis · 2022-11-29 09:30
Yes, ``eval`` is only really acceptable if you have to run code acquired from input (e. g., by ``read``), and safety is not an issue. Without seeing your program, I can't give a more concrete advice; but the general idea would be to organize the substantive part of your processor as a recursive helper function (or a set of functions), and make the macro call that function. You can see it, for instance, in the Trivia library¹: the macros ``match0``, ``ematch0``, etc. are thin wrappers around the function ``parse-patterns``, and this, in turn, calls the function ``make-pattern-predicate``, which performs the recursive destructuring of patterns. ¹ https://github.com/guicho271828/trivia/blob/master/level0/impl.lisp‌
github-alphapapa · 2022-11-29 14:13
A few suggestions: 1. Study the built-in Emacs library, `pcase`. 2. See other relevant Elisp libraries cataloged here: https://github.com/alphapapa/emacs-package-dev-handbook#destructuring 3. Consider registering a new account with a different name.
ieure · 2022-11-29 21:01
When writing more complicated macros, I find it very helpful to factor their logic out into helper functions, which get called from the main `defmacro` definition. Hard to tell without seeing any code, but it sounds like this might be a good approach for your problem.