# Why is typeof not type inferable in this case?

**URL:** <https://discourse.julialang.org/t/why-is-typeof-not-type-inferable-in-this-case/99297>\
**Category:** Performance\
**Created:** [May 23, 2023, 4:33pm UTC](https://discourse.julialang.org/t/why-is-typeof-not-type-inferable-in-this-case/99297 "2023-05-23T16:33:37Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Larbino1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larbino1/32/37831_2.png) [@Larbino1](https://discourse.julialang.org/u/Larbino1)\
**Post date:** [May 23, 2023, 4:33pm UTC](https://discourse.julialang.org/t/why-is-typeof-not-type-inferable-in-this-case/99297/1 "2023-05-23T16:33:37Z")

</div>

I’m messing around with ForwardDiff, trying to write some type stable code, and have found an instance where `typeof` does not properly infer the type. I’m a bit stuck as to what to try here!

I think this particular function used to infer properly, before I switched to Julia 1.9, but many other things have changed as well…

The function in question:

```julia
function hessian(f, x::SVector)
    # T = typeof(HessiansTag(x))
    T = typeof(Tag(f, eltype(x)))
    d1 = dualize(T, x)
    d2 = dualize(T, d1)
    yd2 = f(d2)
    yd1 = value(T, yd2)
    val = value(T, yd1)
    dgrad = extract_jacobian(T, yd2, x)
    grad = value(T, dgrad)    
    hess = extract_jacobian(T, dgrad, x)
    result = DiffResults.ImmutableDiffResult(val, (grad, hess))
    return result
end

```

The output of @code\_warntype is below.  
Note that %2 is infered, but typeof(%2) is not

```julia
MethodInstance for ForwardDiff.hessian(::RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, ::StaticArraysCore.SVector{9, Float64})
  from hessian(f, x::StaticArraysCore.SVector) @ RobotDynamics.Hessians C:\Users\dan_l\Dropbox (Cambridge University)\shared_Daniel\code\RobotDynamics.jl\src\hessians.jl:47
Arguments
  #self#::Core.Const(ForwardDiff.hessian)
  f::RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}
  x::StaticArraysCore.SVector{9, Float64}
Locals
  result::DiffResults.ImmutableDiffResult{2}
  hess::Any
  grad::Any
  dgrad::Any
  val::Any
  yd1::Any
  yd2::Any
  d2::Any
  d1::Any
  T::Type{ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}}
Body::DiffResults.ImmutableDiffResult{2}
1 ─ %1 = RobotDynamics.Hessians.eltype(x)::Core.Const(Float64)
│ %2 = RobotDynamics.Hessians.Tag(f, %1)::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}())
│ (T = RobotDynamics.Hessians.typeof(%2))
│ (d1 = RobotDynamics.Hessians.dualize(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), x))
│ (d2 = RobotDynamics.Hessians.dualize(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), d1))
│ (yd2 = (f)(d2))
│ (yd1 = RobotDynamics.Hessians.value(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), yd2))
│ (val = RobotDynamics.Hessians.value(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), yd1))
│ (dgrad = RobotDynamics.Hessians.extract_jacobian(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), yd2, x))
│ (grad = RobotDynamics.Hessians.value(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), dgrad))
│ (hess = RobotDynamics.Hessians.extract_jacobian(T::Core.Const(ForwardDiff.Tag{RobotDynamics.var"#f_kinematics#8"{RobotDynamics.RBTree{22, Union{RobotDynamics.Prismatic{Float64, Int64}, RobotDynamics.Revolute{Float64, Int64}, RobotDynamics.Rigid{Float64}, RobotDynamics.Rail{Float64, Int64}}}}, Float64}), dgrad, x))
│ %12 = DiffResults.ImmutableDiffResult::Core.Const(DiffResults.ImmutableDiffResult)
│ %13 = val::Any
│ %14 = Core.tuple(grad, hess)::Tuple{Any, Any}
│ (result = (%12)(%13, %14))
└── return result

```

---

<div class="post-metadata">

**Author:** ![Larbino1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larbino1/32/37831_2.png) [@Larbino1](https://discourse.julialang.org/u/Larbino1)\
**Post date:** [May 23, 2023, 4:35pm UTC](https://discourse.julialang.org/t/why-is-typeof-not-type-inferable-in-this-case/99297/2 "2023-05-23T16:35:15Z")

</div>

Curiously, the syntax highlighting here is different to in VSCode.

```julia
var"#f_kinematics#8"

```

was not being highlighted in red in my VSCode terminal.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [May 23, 2023, 7:13pm UTC](https://discourse.julialang.org/t/why-is-typeof-not-type-inferable-in-this-case/99297/3 "2023-05-23T19:13:43Z")

</div>

My guess is [this](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing), but that _shouldn’t_ have been in play because you do use `f` in a head position. In any case, try

```julia
function hessian(f::F, x::SVector) where F

```

I couldn’t verify that this fixed it because you don’t have all the exports from `ForwardDiff` listed and I didn’t try to locate them all myself.
