# A macro for automatic output generation

**URL:** <https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994>\
**Category:** New to Julia\
**Tags:** macros, logging\
**Created:** [June 16, 2021, 7:26am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994 "2021-06-16T07:26:46Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [June 16, 2021, 7:26am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/1 "2021-06-16T07:26:46Z")

</div>

Hi you all,  
suppose I have a function `my_func(args...; kwargs...)`. For example,

```julia
function my_func(a, b)
    a + b
end

```

I would like to manipulate the function with a macro to make a function whose output contains macroed(?) values. For example,

```julia
function my_func(a, b)
    @log a
    @log c = b^2
    a + b
end

```

with a function `Generator` makes a new function such that `my_func2 = Generator(my_func)` where

```julia
function my_func2(a, b)
    Dict(:a => a, :c => b^2)
end

```

Is it possible? If so, how can I achieve this?

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [June 16, 2021, 8:41am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/2 "2021-06-16T08:41:28Z")

</div>

Would something like this work

```julia
julia> using Logging

julia> function wrap(f)
          (a,b) -> begin
             @info a
             @info "c=$(b^2)"
             f(a,b)
          end
       end
wrap (generic function with 1 method)

julia> f(a,b) = a+b
f (generic function with 1 method)

julia> wf = wrap(f)
#1 (generic function with 1 method)

julia> wf(2,3)
[ Info: 2
[ Info: c=9
5

```

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [June 16, 2021, 8:53am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/3 "2021-06-16T08:53:49Z")

</div>

Sorry but it’s not what I wanted.  
I would like “not to” rewrite some logging lines (e.g., `a` or `c = b^2`) for logging.  
I hope that just putting a macro `@log` in front of a variable that I want to log in `my_func`.

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [June 16, 2021, 8:55am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/4 "2021-06-16T08:55:05Z")

</div>

I can’t see the logic behind the` c=b^2` line.  
Do you want to automatically log the input parameters?

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [June 16, 2021, 8:57am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/5 "2021-06-16T08:57:50Z")

</div>

Yes.

> [@iHany](#):
>
> ```julia
> function my_func(a, b)
> a + b
> end
> 
> ```

Only for the use of `my_func`, it’s enough. However, I’d like to add a macro `@log` such as

> [@iHany](#):
>
> ```julia
> function my_func(a, b)
> @log a
> @log c = b^2
> a + b
> end
> 
> ```

and passing a function or macro to make a new function

> [@iHany](#):
>
> ```julia
> function my_func2(a, b)
> Dict(:a => a, :c => b^2)
> end
> 
> ```

which is “annotated” variables in `my_func`.

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [June 16, 2021, 9:01am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/6 "2021-06-16T09:01:43Z")

</div>

So you want to add a `@log` macro to a function which should log its input parameters based on the output of `my_func2`?

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [June 16, 2021, 9:07am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/7 "2021-06-16T09:07:48Z")

</div>

Umm… My explanation was probably poor. Sorry.

What I want is,

1. write a function (in the above example, `my_func`) which contains `@log` macro to indicate which variable will be saved.
2. passing a function (namely, `Generator`) so that `Generator(my_func)` produces a function like

```julia
function my_func2(a, b) # the same arguments with `my_func`
    """
    the below lines would be the same as `my_func`; not manually written, but probably written by `Generator` and assisted by `@log`.
    """
    a = a
    c = b^2
    # output is a dictionary containing variables annotated by `@log`
    Dict(:a => a, :c => c)
end

```

That is, `@log` indicates which variable will be saved, and `Generator` will automatically transform `my_func` to `my_func2` (recognising `@log`).

Actually, I’m not sure the above idea works properly. It’s just an idea 🙂

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [June 16, 2021, 9:18am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/8 "2021-06-16T09:18:07Z")

</div>

Ah okay 🙂  
So you probably need another macro in front of the function as you have to modify parts surrounding the marked lines.

1.) So you would need an object holding your return values(`returndict = Dict()`)  
2.) every log line then converts to something like

```julia
# @log c=b^2
c = b^2
returndict[Symbol("c")] = b^2

```

3.) at the end insert a `return returndict`

Sadly I don’t have experience with nested macros

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [June 16, 2021, 9:38am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/9 "2021-06-16T09:38:51Z")

</div>

Exactly what I’m looking forward 🙂

Do you have any idea to achieve this functionality without nested macros?

---

<div class="post-metadata">

**Author:** ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)\
**Post date:** [June 16, 2021, 9:50am UTC](https://discourse.julialang.org/t/a-macro-for-automatic-output-generation/62994/10 "2021-06-16T09:50:54Z")

</div>

No, at the moment I think this is only possible by using macros, but I could be wrong.
