# Can anyone improve this macro?

**URL:** https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359
**Category:** General Usage
**Tags:** macros, scope, assignment
**Created:** [March 25, 2025, 4:54pm UTC](https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359 "2025-03-25T16:54:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)
#### Post date: [March 25, 2025, 4:54pm UTC](https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359/1 "2025-03-25T16:54:34Z")

</div>

I have written the following macro:

```julia
using Logging

"""
    @no_logging(code_to_execute)

Execute `code_to_execute` sending all logging to the [`Logging.NullLogger`](@ref).

"""
macro no_logging(code)
    return :( with_logger(NullLogger()) do
                 $(esc(code))
             end)
end

```

It seems to work almost as I want it to, the only problem that I have encountered is that it cannot handle assignments, e.g.

```julia
a = 0
@no_logging a = sin(8)
@assert a == sin(8)

```

would create a local variable `a` and which would go out of scope on the next line making the assertion fail. Is there a way to fix this?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 25, 2025, 5:06pm UTC](https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359/2 "2025-03-25T17:06:42Z")

</div>

What about `a = @nologging sin(8)`?

---

<div class="post-metadata">

### Author: ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)
#### Post date: [March 25, 2025, 5:14pm UTC](https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359/3 "2025-03-25T17:14:21Z")

</div>

Yes, that is how I deal with the issue now, but if `@no_logging` could handle any code then it could be offered as a contribution to a respected library like `LoggingExtras.jl` or maybe even the `Logging` standard library.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [March 26, 2025, 4:05am UTC](https://discourse.julialang.org/t/can-anyone-improve-this-macro/127359/4 "2025-03-26T04:05:37Z")

</div>

Depending on what pre-transformed code you want to support, this can go from fairly simple to frustratingly complex. If you only need to support the one assignment, then it’s just turning `@no_logging a = sin(8)` into `a = with_logger(NullLogger()) do; sin(8) end`, as `with_logger` returns the result of its input function call and the `a` assignment remains in the scope it occurs in.

However, things get more complicated with block expressions. A `begin` block could hold multiple assignments, so you’d have to make the `with_logger` call return multiple values for assignment to multiple variables `a, b, c = with_logger(...)`. You’d generally want the block expression to remain outside the `with_logger` call so the assignment occurs where (`let` introduces a nested layer of local scope) and when (`if` makes code conditional) it should. However, that involves unintuitive rules about what part of the expression counts as `code`.

Implicit scope-introducing macros are generally this difficult; think of how the global scope evaluation of `BenchmarkTools` throws people off, and `eval` of the input expression in the global scope is already the simplest situation. You can save almost as much typing with a derivative higher-order function instead of a macro with specific rules:

```julia
null_log(f) = with_logger(f, NullLogger())

a = null_log() do; sin(8) end

```

which will be easier for users to control the scope of their variable assignments.
