# Defining a global variable in a nested quote

**URL:** <https://discourse.julialang.org/t/defining-a-global-variable-in-a-nested-quote/91724>\
**Category:** General Usage\
**Tags:** metaprogramming, scope\
**Created:** [December 16, 2022, 3:44am UTC](https://discourse.julialang.org/t/defining-a-global-variable-in-a-nested-quote/91724 "2022-12-16T03:44:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![HashBrown](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hashbrown/32/43601_2.png) [@HashBrown](https://discourse.julialang.org/u/HashBrown)\
**Post date:** [December 16, 2022, 3:44am UTC](https://discourse.julialang.org/t/defining-a-global-variable-in-a-nested-quote/91724/1 "2022-12-16T03:44:07Z")

</div>

Suppose we have the following code:

```julia
foo() = begin
    var_name = gensym()
    is_init_var_name = gensym()

    quote
        const $is_init_var_name = Ref{Bool}(false)

        set_val(x) = begin
            if $is_init_var_name[]
                $var_name[] = x
            else
                $is_init_var_name[] = true
                quote
                    const $$var_name = Ref{$(x |> typeof)}($x)
                end |> eval
            end
        end

        get_val() = $var_name[]

        is_val_init() = $is_init_var_name[]
    end |> eval
end

```

After calling `foo()` we can check that `is_val_init` indeed returns false. Calling `get_val()` is an error: `UndefVarError: ##312 not defined` which is also expected.

What I am confused about is why when I call set\_val(100) I get the error: `UndefVarError: ##312 not defined` again.

It seems that the double dollar sign is not interpolating as I am expecting. It seems to be trying to access the underlying value referred to the by the symbol that is `var_name`. When in reality I am just trying to get the symbol so I can assign to it the same way I did with `is_init_var_name` in the un-nested quote.

A single dollar sign also won’t work for obvious reasons. That is `var_name` is not a variable in the function `set_val`.

I need the result to be a `global constant Ref `for performance reasons. I can achieve a global variable by just not using a nested quote and using the keyword `global`. But then it wouldn’t be `const `which doesn’t work for me.

---

<div class="post-metadata">

**Author:** ![HashBrown](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hashbrown/32/43601_2.png) [@HashBrown](https://discourse.julialang.org/u/HashBrown)\
**Post date:** [December 16, 2022, 3:53am UTC](https://discourse.julialang.org/t/defining-a-global-variable-in-a-nested-quote/91724/2 "2022-12-16T03:53:10Z")

</div>

It seems the following hack works:

```julia
foo() = begin
    var_name = gensym()
    var_name_str = string(var_name)
    is_init_var_name = gensym()

    quote
        const $is_init_var_name = Ref{Bool}(false)

        set_val(x) = begin
            if $is_init_var_name[]
                $var_name[] = x
            else
                $is_init_var_name[] = true
                var_name_local = Symbol($var_name_str)
                quote
                    const $var_name_local = Ref{$(x |> typeof)}($x)
                end |> eval
            end
        end

        get_val() = $var_name[]

        is_val_init() = $is_init_var_name[]
    end |> eval
end

```

I don’t know if there is just something hacky solution built into Julia that interprets single dollar signs in front of an assignment differently than elsewhere (interpolates to the Symbol rather than the underlying value). And somehow that solution is not extending to double dollar signs and the like.

Does anyone know more about this?
