R (yes, the statistics language) has exactly this.
You can literally extract the body of a function as a list of "call" objects (which are themselves just dressed-up lists of symbols), inject/delete/modify individual statements, and then re-cast your new list to a new function object. Or you can construct new functions from scratch this way.
I've written utilities before that will inline specific function calls within the body of another function, or that implement function composition by constructing a new function from scratch.
I don't know why the original devs thought this was necessary or even desirable in a statistics package, but it turns out to be a lot of fun to program with. It has also made possible a wide variety of clever and elegant custom syntaxes, such as a pipe infix operator implemented as a 3rd-party library without any custom language extensions [0]. The pipe infix operator got so popular that it was eventually made part of the language core syntax in version 4.1 [1].
You can literally extract the body of a function as a list of "call" objects (which are themselves just dressed-up lists of symbols), inject/delete/modify individual statements, and then re-cast your new list to a new function object. Or you can construct new functions from scratch this way.
I've written utilities before that will inline specific function calls within the body of another function, or that implement function composition by constructing a new function from scratch.
I don't know why the original devs thought this was necessary or even desirable in a statistics package, but it turns out to be a lot of fun to program with. It has also made possible a wide variety of clever and elegant custom syntaxes, such as a pipe infix operator implemented as a 3rd-party library without any custom language extensions [0]. The pipe infix operator got so popular that it was eventually made part of the language core syntax in version 4.1 [1].
[0]: https://magrittr.tidyverse.org/
[1]: https://www.r-bloggers.com/2021/05/the-new-r-pipe/