Constant propagation of kwargs possible?

I suspect the answer is ‘no’, but is current Julia able to constant-propagate kwargs? In other words, is it possible to make the following infer in some way while preserving the kwarg?

Julia 1.2

julia> h(; n) = ntuple(_ -> 1, n);

julia> f() = h(n = 3);

julia> @code_warntype f()
Variables
  #self#::Core.Compiler.Const(f, false)

Body::Tuple{Vararg{Int64,N} where N}
...

(Using a positional argument instead of a kwarg works, of course, but I’d rather not give up my kwargs in my current real-world application)

julia> h(n) = ntuple(_ -> 1, n);

julia> f() = h(3);

julia> @code_warntype f()
Variables
  #self#::Core.Compiler.Const(f, false)

Body::Tuple{Int64,Int64,Int64}
...
1 Like

This doesn’t directly answer your question, but I found it interesting to see that using a named tuple as a positional argument does work:

julia> h(nt) = ntuple(_ -> 1, nt.n)
h (generic function with 1 method)

julia> f() = h((n = 3,))
f (generic function with 1 method)                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                      
julia> @code_warntype f()
Body::Tuple{Int64,Int64,Int64}
1 ─     return (1, 1, 1)
2 Likes

Nice! Which probably means that constant propagation could in principle be made to work also on kwargs, no? (I say this because I vaguely recall reading that kwargs work with named tuples internally, but I might be wrong)

Yes. See:

julia> ((; kwargs...) -> kwargs.data)(n=1) :: NamedTuple
(n = 1,)

You can also see that @code_warntype f() creates a NamedTuple.

1 Like