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.