# Generating function from existing function body + custom return statement

**URL:** https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212
**Category:** General Usage
**Tags:** metaprogramming
**Created:** [April 13, 2021, 3:59pm UTC](https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212 "2021-04-13T15:59:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)
#### Post date: [April 13, 2021, 3:59pm UTC](https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212/1 "2021-04-13T15:59:34Z")

</div>

Hello,

I’m exploring an idea which may look funny. Please tell me if you thinks it’s impossible or useless.

## My goal

I’d like to generate automatically (with metaprogramming I guess) _functions_ which body and signature comes from an existing _function “template”_ and then _appending a return statement_ (`return myvar` where `myvar` can be decided in the code). Here is an illustration.

The function “template” `model` is a model of physical system which computes many variables (only 3 (`c`,`d`,`e`) in this dummy example).

```julia
function model(a,b)
    c = 2*a
    d = c+b
    e = d^2
end

```

To provide more context, this model will be used in several optimization variants, like:

- minimize `d`
- minimize `d` s.t. `e` ≤ 2
- minimize `e`+`d`
- …

These variants should be user selectable.  
To support the variants without duplicating the code of `model`, I’d like an easy way for the user my optimization tool to select the relevant output(s) of `model`. So I’ve imagined I could have macro which could be invoked as:

```julia
@set_return model_retc model :c

```

And this would generate the function:

```julia
function model_retc(a,b) # function name set in macro invokation
    # signature and body copy-pasted from `model`
    c = 2*a
    d = c+b
    e = d^2
    return c # returned variable(s) set in macro invokation
end

```

It’s not clear to me how to do this. I’ve searched two approaches:

1. Get the AST of the template function, but I kind of understood that AST is defined for specific methods rather than the generic function (SO: [Access the AST for generic functions in Julia](https://stackoverflow.com/questions/14124456/access-the-ast-for-generic-functions-in-julia))
2. Get the source code of the template function, but I didn’t go all the way. Only, I found on SO [How to print in REPL the code of functions in Julia?](https://stackoverflow.com/questions/37662365/how-to-print-in-repl-the-code-of-functions-in-julia) which seems to indicate that it’s not working for REPL-defined functions.

- Also, the `@less` macro is about opening the source in a pager, but I just want to get the source in a variable.

Also, I got from [Write Julia macro that returns a function](https://stackoverflow.com/questions/65340401/write-julia-macro-that-returns-a-function) that to create a function in a macro, it is necessary to have the the content known at compile time, not at execution time. I think in my case all information is available in the source code.

## Alternative without metaprogramming: is it good enough?

Since I don’t know how to achieve my goal with metaprogramming, I’m using an approach based on 1) returning all variables of potential interest and 2) select those in a wrapper.

The function which return “all” is:

```julia
function model_retall(a,b)
    c = 2*a
    d = c+b
    e = d^2
    return Dict(:c => c, :d => d, :e => e)
end

```

Then I can create (manually or with a short function factory):

```julia
function model_retc(a,b)
    model_retall(a,b)[:c]
end

```

My questions on this metaprogramming-less approach are:

- Are there better alternatives than returning a `Dict` of variables?
  - This approach is actually insired by an existing Python tool which enforces a convention that all model functions should `return locals()`, i.e. all local variables?

- Is there some performance issue related to returning many outputs kike in `model_retall` and then dropping most of them (e.g. `d` and `e` ends up being unnecessary to compute `c`)
  - in particular, in my optimization approach, I want to compute the gradient of `model_retc` with _some AD package_ (ForwardDiff, Zygote, other…?)

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [April 13, 2021, 4:09pm UTC](https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212/2 "2021-04-13T16:09:02Z")

</div>

You can return a named tuple:

```julia
julia> function model(a,b)
           c = 2 * a
           d = c + b
           e = d ^ 2
           return (c = c, d = d, e = e)
       end
model (generic function with 1 method)

julia> t = model(1, 2)
(c = 2, d = 4, e = 16)

julia> t.c
2

```

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [April 13, 2021, 4:54pm UTC](https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212/3 "2021-04-13T16:54:18Z")

</div>

Definitely agreed–returning a `NamedTuple` should work very well in this case. Furthermore, you can write a function to select the relevant field, and you can even use that to create a new function which returns only the field of interest.

For example:

```julia
julia> function model(a,b)
           c = 2 * a
           d = c + b
           e = d ^ 2
           return (c = c, d = d, e = e)
       end
model (generic function with 1 method)

# A new function which calls `model` and then returns the `c` from its named tuple:
julia> model_c(args...) = model(args...).c
model_c (generic function with 1 method)

julia> model_c(1, 2)
2

```

---

<div class="post-metadata">

### Author: ![pierre-haessig](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pierre-haessig/32/217129_2.png) [@pierre-haessig](https://discourse.julialang.org/u/pierre-haessig)
#### Post date: [April 13, 2021, 8:18pm UTC](https://discourse.julialang.org/t/generating-function-from-existing-function-body-custom-return-statement/59212/4 "2021-04-13T20:18:34Z")

</div>

> [@dpsanders](#):
>
> You can return a named tuple:

Thanks for the tip! The dynamic and mutable nature of a Dict is certainly not needed in my case.
