My goal is to create a macro that takes an arbitrary function and adds additional arguments and changes the docstring.

For example, say I define the following function:

```
"This is my function"
function f(a, b; x=1.0, y=1.0)
return a + b + x + y
end
```

And now assume I’d also like to define the following augmented function (where the extra arguments `c`

and `d`

have been added:

```
"This is my augmented function"
function f(a, b, c, d; x=1.0, y=1.0)
return f(a, b; x=x, y=y) + c + d
end
```

I would like to create a macro that can define an augmented function automatically. Ideally, I would just write:

```
@augment begin
"This is my function"
function f(a, b; x=1.0, y=1.0)
return a + b + x + y
end
end
```

and this would define the original function and augmented function to use.

So far I have tried using MacroTools.jl as follows:

```
using MacroTools
macro augment(expr)
# Evaluate original function expression
func = eval(expr)
# Split function definition into dictionaries
func_dict = MacroTools.splitdef(expr)
new_dict = deepcopy(func_dict)
# Change new function bodies
new_dict[:body] = :($func($(func_dict[:args]...); $(func_dict[:kwargs]...)) + c + d)
# Change new function Arguments
push!(new_dict[:args], :c, :d)
# Convert back to expressions and evaluate
eval(MacroTools.combinedef(new_dict))
return nothing
end
```

The above code successfully augments functions with `c`

and `d`

arguments, however, there are two problems. Firstly, the keyword arguments in the augmented function are always set to their default value, such that calling `f(1, 2, 3, 4; x=5, y=6)`

acutally calls `f(1, 2, 3, 4; x=1.0, y=1.0)`

. Secondly, the `@augment`

macro above does not handle the docstring conversion. As soon as I enter a doctring to the function, the `MacroTools.splitdef(expr)`

fails.

This task is proving quite difficult to me so any help is appreciated.