# How would macros make this code clearer?

**URL:** <https://discourse.julialang.org/t/how-would-macros-make-this-code-clearer/103702>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [September 9, 2023, 2:40pm UTC](https://discourse.julialang.org/t/how-would-macros-make-this-code-clearer/103702 "2023-09-09T14:40:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jburgy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jburgy/32/11229_2.png) [@jburgy](https://discourse.julialang.org/u/jburgy)\
**Post date:** [September 9, 2023, 2:40pm UTC](https://discourse.julialang.org/t/how-would-macros-make-this-code-clearer/103702/1 "2023-09-09T14:40:57Z")

</div>

I have been mildly obsessed with the [Thompson’s construction algorithm](https://en.wikipedia.org/wiki/Thompson%27s_construction) and recently implemented a [version of it in julia](https://github.com/jburgy/blog/blob/master/fun/regexp.jl). I also wrote a [couple blog posts](https://bur.gy/2022/05/27/what-makes-julia-delightful.html) for additional context. This code works but feels like it could be more idiomatic if only I grokked [julia metaprogamming](https://docs.julialang.org/en/v1/manual/metaprogramming/) better. Specifically, I am constructing a collection of matching fragments as a `Dict{Symbol,Tuple{Expr,Vararg{Expr}}}` so I can convert them to separate functions and implement the regexp matching as an interpreter (see [`function match`](https://github.com/jburgy/blog/blob/52b6b1d0225f0e7756558c196a8e1b718aa15091/fun/regexp.jl#L142-L153)) or inline them into a specialized matcher (see [`function jit`](https://github.com/jburgy/blog/blob/52b6b1d0225f0e7756558c196a8e1b718aa15091/fun/regexp.jl#L155-L184)). How can I get rid of `exprs` altogether, define `char!`, `posstar!`, etc _directly_ as functions yet still access their AST to inline them in a specialized matcher?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [September 9, 2023, 8:29pm UTC](https://discourse.julialang.org/t/how-would-macros-make-this-code-clearer/103702/2 "2023-09-09T20:29:58Z")

</div>

Disclaimer: I briefly looked at your code but it’s a bit too complex to understand in a couple of minutes. I think I have a highlevel understanding of how it works though.

IIUC, you have a dict with `functionname->body` from which you either generate Julia function to use in the “interpreter mode” or you, in “compiler mode”, stitch them together into a single function expression for Julia to compile. The latter part you don’t like. While I personally think that approach is fine, you probably don’t need to inline yourself. You can simply tell Julia to inline the function (by adding `@inline` to where you define the functions) and then you don’t need to handle the function bodies as expressions anymore.

To give you a better picture of what “metaprogramming with macros” is: Think of it like syntactic sugar. If you notice you need to write somewhat repetitive code with a clear pattern but much less “actual data” then there might be room for a macro. When trying to design a macro after having identified such a repetively, well-structured code fragment, I usually try to write down what I actually _would like_ to write instead (that is still valid Julia code). Then the macro just needs to translate what I want to write into what I need to write. And that’s the essence of what macros are and do. I don’t really a good macro opportunity for your code here, except maybe doing a string macro like Julia’s regex-strings, that takes a pattern string and replaces it with the matching function. This macro could be written very little effort given your current codebase.

---

<div class="post-metadata">

**Author:** ![jburgy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jburgy/32/11229_2.png) [@jburgy](https://discourse.julialang.org/u/jburgy)\
**Post date:** [September 10, 2023, 8:32pm UTC](https://discourse.julialang.org/t/how-would-macros-make-this-code-clearer/103702/3 "2023-09-10T20:32:45Z")

</div>

Thank you [abraemer](https://discourse.julialang.org/u/abraemer) for taking the time to look at my code, however briefly. Thank you to the entire community as well for giving me this [rubberducking](https://en.wikipedia.org/wiki/Rubber_duck_debugging) opportunity. Explaining what I didn’t like about my code crystallized how I could improve it. I didn’t like how I dissected simple functions because I couldn’t extract their body as an AST. [Quoting](https://docs.julialang.org/en/v1/manual/metaprogramming/#Quoting) them was the obvious work-around but I approached it the wrong way. I didn’t need to rewrite every function as quoted body and args then generate them later. Instead, I can quote the _entire chunk_ of code where those functions are defined so I can [evaluate](https://docs.julialang.org/en/v1/base/base/#Core.eval) it _and_ access their bodies by walking the [AST](https://docs.julialang.org/en/v1/devdocs/ast/). [0e00457](https://github.com/jburgy/blog/blob/0e00457b606d9d6ab65b8c3ea8c202f2479832b2/fun/regexp.jl) looks much more like [e3e5bc7](https://github.com/jburgy/blog/blob/e3e5bc76bed152fe4c8641c2204bb87af53af4b5/fun/regexp.jl) with

```julia
matchers = quote
# all function definitions
end

exprs = Dict{Symbol,Tuple{Expr,Vararg{Expr}}}(
    expr.args[1].args[1] => (expr.args[2], expr.args[1].args[2:end-4]...)
    for expr in matchers.args if is_expr(expr, :function)
)

eval(matchers)

```

I like this better because it’s so much less intrusive.
