# Is there a way to apply constant folding with \`nameof\` for a simple \`UnionAll\`?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [March 7, 2021, 4:54am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653 "2021-03-07T04:54:39Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kimikage](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kimikage/32/14534_2.png) [@kimikage](https://discourse.julialang.org/u/kimikage)\
**Post date:** [March 7, 2021, 4:54am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/1 "2021-03-07T04:54:39Z")

</div>

`nameof(::UnionAll)` does not perform constant folding.

```julia
julia> @code_typed nameof(Complex{Float32})
CodeInfo(
1 ─ return :Complex
) => Symbol

julia> @code_typed nameof(Complex)
CodeInfo(
1 ─ nothing::Nothing
2 ┄ %2 = φ (#1 => _2, #3 => %6)::Any
│ %3 = (%2 isa Base.UnionAll)::Bool
└── goto #4 if not %3
3 ─ %5 = π (%2, UnionAll)
│ %6 = Base.getfield(%5, :body)::Any
└── goto #2
4 ─ goto #5
5 ─ %9 = Base.nameof(%2)::Any
│ Core.typeassert(%9, Base.Symbol)::Symbol
│ %11 = π (%9, Symbol)
└── return %11
) => Symbol

```

At first I thought it was because `@nospecialize` was specified in `Base.unwrap_unionall`, but that doesn’t seem to be the case. Of course, the `body` field of `UnionAll` is boxed, so it should require special handling.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 7, 2021, 5:02am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/2 "2021-03-07T05:02:43Z")

</div>

New, in Julia 1.7:

```julia
julia> Base.@aggressive_constprop constprop_unwrap(::Type{T}) where {T} = nameof(T)
constprop_unwrap (generic function with 1 method)

julia> @code_typed constprop_unwrap(Complex{Float32})
CodeInfo(
1 ─ return :Complex
) => Symbol

```

I’d do something like

```julia
@static if VERSION >= v"1.7.0-DEV.421" 
Base.@aggressive_constprop constprop_unwrap(::Type{T}) where {T} = nameof(T)
else
@generated constprop_unwrap(::Type{T}) where {T} = QuoteNode(nameof(T))
end

```

to add support for older Julia versions.

---

<div class="post-metadata">

**Author:** ![kimikage](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kimikage/32/14534_2.png) [@kimikage](https://discourse.julialang.org/u/kimikage)\
**Post date:** [March 7, 2021, 5:13am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/3 "2021-03-07T05:13:21Z")

</div>

Today I learned about `@aggressive_constprop`. Thank you.  
However, I don’t think we have achieved the original goal.

```julia
julia> @code_typed constprop_unwrap(Complex)
CodeInfo(
1 ─ %1 = invoke Main.nameof($(Expr(:static_parameter, 1))::UnionAll)::Symbol
└── return %1
) => Symbol

```

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 7, 2021, 5:16am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/4 "2021-03-07T05:16:57Z")

</div>

Oops, you’re right. Just stick with the `@generated` version then.

```julia
julia> Base.@aggressive_constprop constprop_unwrap(::Type{T}) where {T} = nameof(T)
constprop_unwrap (generic function with 1 method)

julia> @generated generated_unwrap(::Type{T}) where {T} = QuoteNode(nameof(T))
generated_unwrap (generic function with 1 method)

julia> @code_typed constprop_unwrap(Complex{Float32})
CodeInfo(
1 ─ return :Complex
) => Symbol

julia> @code_typed generated_unwrap(Complex{Float32})
CodeInfo(
1 ─ return :Complex
) => Symbol

julia> @code_typed constprop_unwrap(Complex)
CodeInfo(
1 ─ %1 = invoke Main.nameof($(Expr(:static_parameter, 1))::UnionAll)::Symbol
└── return %1
) => Symbol

julia> @code_typed generated_unwrap(Complex)
CodeInfo(
1 ─ return :Complex
) => Symbol

```

---

<div class="post-metadata">

**Author:** ![kimikage](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kimikage/32/14534_2.png) [@kimikage](https://discourse.julialang.org/u/kimikage)\
**Post date:** [March 7, 2021, 5:40am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/5 "2021-03-07T05:40:42Z")

</div>

`@generated` function is a powerful tool, but it is a little too powerful. In the use case I’m envisioning, the output of `nameof` is used for conditional branching and not for the final output. In other words, once the compilation is done, there is no need to remember it anymore.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 7, 2021, 6:15am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/6 "2021-03-07T06:15:28Z")

</div>

I don’t follow. What do you mean by “remember”?  
You want a function to compile, but not be “saved”? I don’t think that is possible for ordinary functions either. Methods and a lot of metadata (e.g. inference results) will be cached.

If you’re only using the results once, then that implies latency is more important than compile times, so spending more time on inference/const prop isn’t worth it?

---

<div class="post-metadata">

**Author:** ![kimikage](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kimikage/32/14534_2.png) [@kimikage](https://discourse.julialang.org/u/kimikage)\
**Post date:** [March 7, 2021, 6:39am UTC](https://discourse.julialang.org/t/is-there-a-way-to-apply-constant-folding-with-nameof-for-a-simple-unionall/56653/7 "2021-03-07T06:39:11Z")

</div>

> [@Elrod](#):
>
> I don’t think that is possible for ordinary functions either. Methods and a lot of metadata (e.g. inference results) will be cached.

I agree. So I would like it to behave like a ordinary function.
