julia icon indicating copy to clipboard operation
julia copied to clipboard

Constant propagation through NamedTuple destructuring

Open bramtayl opened this issue 4 years ago • 3 comments
trafficstars

You can break apart a NamedTuple into pairs and then rebuild it, which is very convenient, especially for programmatically building NamedTuples. However, constant propagation doesn't keep up through the process:

rebuild(named_tuple) = named_tuple |> pairs |> Tuple |> NamedTuple
@code_warntype rebuild((a = 1, b = 1.0, c = "1"))
# inferred result: NamedTuple
# would hope for: NamedTuple{(:a, :b, :c), Tuple{Int64, Float64, String}}

I wonder if it would be feasible for this to work in the first place, and if so, what the steps would be to getting there?

Ref https://github.com/JuliaLang/julia/issues/39910#issuecomment-826845402

bramtayl avatar Apr 27 '21 12:04 bramtayl

I watched the JuliaCon talk where @StefanKarpinski mentioned prioritizing making Julia faster for tabular data and I think solving this would be an important step

bramtayl avatar Aug 13 '21 16:08 bramtayl

There two issues here:

  1. Tuple{::Pairs) looks suboptimal, only giving Tuple{Vararg{Pair{Int64, Pair{Symbol}}}} here. x -> (x...,) gives the slightly better NTuple{3, Pair{Int64, Pair{Symbol}}}, but still looses all const-ness.
  2. Even if NamedTuple gets a const tuple of pairs, it still only infers as NamedTuple:
julia> foo() = NamedTuple((:a => 1, :b => 1.0, :c => "1"))
foo (generic function with 1 method)

julia> @code_warntype foo()
MethodInstance for foo()
  from foo() in Main at REPL[21]:1
Arguments
  #self#::Core.Const(foo)
Body::NamedTuple
1 ─ %1 = (:a => 1)::Core.Const(:a => 1)
│   %2 = (:b => 1.0)::Core.Const(:b => 1.0)
│   %3 = (:c => "1")::Core.PartialStruct(Pair{Symbol, String}, Any[Core.Const(:c), String])
│   %4 = Core.tuple(%1, %2, %3)::Core.PartialStruct(Tuple{Pair{Symbol, Int64}, Pair{Symbol, Float64}, Pair{Symbol, String}}, Any[Core.Const(:a => 1), Core.Const(:b => 1.0), Core.PartialStruct(Pair{Symbol, String}, Any[Core.Const(:c), String])])
│   %5 = Main.NamedTuple(%4)::NamedTuple
└──      return %5

martinholters avatar Aug 19 '21 13:08 martinholters

Thanks for looking into it! It does seem like an uphill battle

bramtayl avatar Aug 19 '21 20:08 bramtayl