In learning Clojure, I came across this fantastic series of tutorials https://aphyr.com/posts/305-clojure-from-the-ground-up-macros
This specific topic on macros explains a bit about expanded function trees and how macros in Clojure and some other Lisps can be used to take advantage of those to rewrite code. This evoked a memory of an MIT OCW class video I watched years ago which was taught using the Scheme flavor of LISP. Since then, MIT switched to Python. But this made me think about how different it must be to start by learning to program by directly writing expression trees. Isn't this what compilers create when they compile languages like Java, C, C#, etc? So...learning LISP languages like Clojure will give you a sense of what is actually happening when those languages are compiled and will give you a base to write a compiler (if you haven't developed those things already). With so many CS programs centered on pragmatism these days (e.g. programming) it may be worthwhile for many CS grads and self-learners to pick up some Clojure with this perspective in mind.