Let us agree to disagree There is no magic here and there are multiple ways to solve this issue.

First of all, as you have said the reason, why the `bignums`

function is not working, related to the fact that `sqrt(big(2))`

is calculated before internal calculations are being made, and it is calculated with default precision, which is equal 256. So the easiest way to overcome this issue is to calculate this function with the necessary precision and here one can use higher order functions

```
julia> @assert join(bignums(setprecision(() -> sqrt(big(2)), 1000), 2, 1000)) == join(@numbers(sqrt(big(2)), 2, 1000))
julia> [join(bignums(setprecision(() -> sqrt(big(2)), u), 2, u)) for u in [10, 20, 30, 40, 1000]
]
5-element Vector{String}:
"10110101000"
"101101010000010011110"
"1011010100000100111100110011010"
"10110101000001001111001100110011111110100"
"10110101000001001111001100110011111110011101111001100100100001000101100101111101100010011011001101110101010010101011111010011111000111010110111101100000101110101000100100111011101010000100110011101101000101111010110010000101100000110011001110011001000101010100101011111100100000110000010000111010101110001010001011000011101010001011000111111110011011111101110010000011110110110011100100001111011101001010100001011110010000111001110001111011010010100111100000000100100001110011011000111101111110100010011101101000110100100010000000101110100001110100001010101111000111110100111001010011000001011001110001100000000100011011110000110011011110111100101010110001101111001001000100010110100010000100010110001010010001100000101010111100011100100010111101111100010011100011001111000110110101011010100010100011100010111011011111101001110111001100101100101010011000110100001100110001111100111100100001001101111101010010111100010010000011111000001101101110010110000010111011101010101001001010000010001001100100000"
```

Not very convenient? Yes. Impossible? No.

One can make it somewhat easier by applying the same idea of high order function to `bignums`

itself.

```
function bignums2(f, b, n = 100)
setprecision(round(Integer, n)) do
reverse(digits(floor(BigInt, big(2)^n*f()), base = b))
end
end
julia> @assert join(bignums2(() -> sqrt(big(2)), 2, 1000)) == join(@numbers(sqrt(big(2)), 2, 1000))
julia> [join(bignums2(() -> sqrt(big(2)), 2, u)) for u in [10, 20, 30, 40, 1000]]
5-element Vector{String}:
"10110101000"
"101101010000010011110"
"1011010100000100111100110011010"
"10110101000001001111001100110011111110100"
"10110101000001001111001100110011111110011101111001100100100001000101100101111101100010011011001101110101010010101011111010011111000111010110111101100000101110101000100100111011101010000100110011101101000101111010110010000101100000110011001110011001000101010100101011111100100000110000010000111010101110001010001011000011101010001011000111111110011011111101110010000011110110110011100100001111011101001010100001011110010000111001110001111011010010100111100000000100100001110011011000111101111110100010011101101000110100100010000000101110100001110100001010101111000111110100111001010011000001011001110001100000000100011011110000110011011110111100101010110001101111001001000100010110100010000100010110001010010001100000101010111100011100100010111101111100010011100011001111000110110101011010100010100011100010111011011111101001110111001100101100101010011000110100001100110001111100111100100001001101111101010010111100010010000011111000001101101110010110000010111011101010101001001010000010001001100100000"
```

If your numbers a result of some function, then it is better to follow this approach instead of falling down to metaprogramming. I mean in real life code, instead of `() -> sqrt(big(2))`

you can use actual function, which produces some `BigInt`

values.

Now, if it is absolutely necessary to use a macro, then one can do something like this

```
macro numbers2(x, b, n = 100)
return quote
setprecision(round(Integer, $(esc(n)))) do
reverse(digits(floor(BigInt, big(2)^$(esc(n))*$(esc(x))), base = $(esc(b))))
end
end
end
julia> @assert join(@numbers2(sqrt(big(2)), 2, 1000)) == join(@numbers(sqrt(big(2)), 2, 1000))
julia> [join(@numbers2(sqrt(big(2)), 2, u)) for u in [10, 20, 30, 40, 1000]]
5-element Vector{String}:
"10110101000"
"101101010000010011110"
"1011010100000100111100110011010"
"10110101000001001111001100110011111110100"
"10110101000001001111001100110011111110011101111001100100100001000101100101111101100010011011001101110101010010101011111010011111000111010110111101100000101110101000100100111011101010000100110011101101000101111010110010000101100000110011001110011001000101010100101011111100100000110000010000111010101110001010001011000011101010001011000111111110011011111101110010000011110110110011100100001111011101001010100001011110010000111001110001111011010010100111100000000100100001110011011000111101111110100010011101101000110100100010000000101110100001110100001010101111000111110100111001010011000001011001110001100000000100011011110000110011011110111100101010110001101111001001000100010110100010000100010110001010010001100000101010111100011100100010111101111100010011100011001111000110110101011010100010100011100010111011011111101001110111001100101100101010011000110100001100110001111100111100100001001101111101010010111100010010000011111000001101101110010110000010111011101010101001001010000010001001100100000"
```

First of all, it returns `quote`

instead of `eval`

, so macro is doing what it should do, i.e. transforming code instead of calculating in compile time. Secondly, I use macro hygene to generate proper code. You can use `@macroexpand`

to verify the result.

```
julia> @macroexpand [join(@numbers2(sqrt(big(2)), 2, u)) for u in [10, 20, 30, 40, 1000]]
:([join(begin
#= REPL[25]:3 =#
Main.setprecision(Main.round(Main.Integer, u)) do
#= REPL[25]:4 =#
Main.reverse(Main.digits(Main.floor(Main.BigInt, Main.big(2) ^ u * sqrt(big(2))),
base = 2))
end
end) for u = [10, 20, 30, 40, 1000]])
```

You can compare this code with the macro without hygene

```
macro numbers3(x, b, n = 100)
return quote
setprecision(round(Integer, $n)) do
reverse(digits(floor(BigInt, big(2)^$n*$x), base = $b))
end
end
end
julia> @macroexpand [join(@numbers3(sqrt(big(2)), 2, u)) for u in [10, 20, 30, 40, 1000]]
:([join(begin
#= REPL[40]:3 =#
Main.setprecision(Main.round(Main.Integer, Main.u)) do
#= REPL[40]:4 =#
Main.reverse(Main.digits(Main.floor(Main.BigInt, Main.big(2) ^ Main.u * Main.sqrt(
Main.big(2))), base = 2))
end
end) for u = [10, 20, 30, 40, 1000]])
```

and from this code, it is easy to understand why Julia throw error.