Extracting Default Arguments from Function Signature

Is there any way to extract the default values from a method’s signature? For example, say I define:

# Function with two keyword arguments that have default values
function f(x, y; kx = 3, ky = 4) end

# Call function without keyword arguments
f(1, 2)

# Extract kx and ky from method call above, without actually executing the function...

I would like to get the values kx = 3 and ky = 4 via inspection / reflection of the method call. I can use @which to get a Method instance:

julia> m = @which f(1, 2)
f(x, y; kx, ky) in Main at REPL[1]:1

julia> m.sig
Tuple{typeof(f), Any, Any}

But that does not contain the unspecified arguments, let alone their default values. Any help would be greatly appreciated.

Best wishes,
Leonard

Welcome, @anicusan. There is a way to do this, but it involves knowing how to parse Julia’s lowered code representation. I’m not sure what your goal is, but unless you’re writing “metacode” (code to analyze code), I hope this isn’t something you expect to use widely in, say, a numeric library. I can’t think of a good reason for it and I worry that doing this could make your code fall victim to nonlocal and history-dependent effects. Consider whether there’s a better approach to what you’re trying to do, like write a function whose sole job it is to compute default values and then call it from your signature line (which also makes it externally callable). Note that if you’re coming from Python: Julia’s default arguments are evaluated at runtime, not definition-time: Common Gotchas — The Hitchhiker's Guide to Python.

That said, hoping that you do have a good reason for wanting to do this, here’s a head start:

julia> lwr = @code_lowered f(1, 2)
CodeInfo(
1 ─ %1 = Main.:(var"#f#12")(3, 4, #self#, x, y)
└──      return %1
)

Then by taking apart the CodeInfo you can get the values you’re looking for.

2 Likes