# Get the argument names of an function

For an arbitrary function

``````function f(x,y,z=3)
p = x+y*z
return p
end
``````

I want to be able take the argument names of `f`

``````julia> argument_names(f)
3-element Array{Symbol,1}:
:x
:y
:z
``````

Is this possible?

``````julia> collect(methods(f))
 f(x, y) in Main at REPL:2
 f(x, y, z) in Main at REPL:2

julia> x = collect(methods(f))
f(x, y, z) in Main at REPL:2

julia> x.slot_syms
"#self#\0x\0y\0z\0p\0"
``````

This is the closest I can get.

1 Like

A hint is that Julia itself can print the arguments. So step into `show` with the debugger:

``````julia> using Debugger

julia> function f(x,y::Integer,z=3)   # just for fun, add a type parameter
p = x+y*z
return p
end
f (generic function with 4 methods)

julia> m = first(methods(f))
f(x, y::Integer) in Main at REPL:2

julia> @enter show(m)
In show(x) at show.jl:325
>325  show(x) = show(stdout::IO, x)

About to run: (typeassert)(Base.TTY(RawFD(0x0000000d) open, 0 bytes waiting), IO)
1|debug> se
In show(x) at show.jl:325
>325  show(x) = show(stdout::IO, x)

About to run: (show)(Base.TTY(RawFD(0x0000000d) open, 0 bytes waiting), f(x, y::Integer) in Main at REPL:2)
1|debug> s
In #show#393(kwtype, , io, m) at methodshow.jl:159
158  function show(io::IO, m::Method; kwtype::Union{DataType, Nothing}=nothing)
>159      tv, decls, file, line = arg_decl_parts(m)
160      sig = unwrap_unionall(m.sig)
161      ft0 = sig.parameters
162      ft = unwrap_unionall(ft0)
163      d1 = decls

1|debug> n
In #show#393(kwtype, , io, m) at methodshow.jl:159
158  function show(io::IO, m::Method; kwtype::Union{DataType, Nothing}=nothing)
159      tv, decls, file, line = arg_decl_parts(m)
>160      sig = unwrap_unionall(m.sig)
161      ft0 = sig.parameters
162      ft = unwrap_unionall(ft0)
163      d1 = decls
164      if sig === Tuple

About to run: (getproperty)(f(x, y::Integer) in Main at REPL:2, :sig)
1|julia> decls
3-element Array{Tuple{String,String},1}:
("", "typeof(f)")
("x", "")
("y", "Integer")
``````
6 Likes

using the following code from https://github.com/JuliaLang/julia/blob/master/base/methodshow.jl (`Vector{Any}` changed to `Vector{Symbol}`)

``````function method_argnames(m::Method)
argnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), m.slot_syms)
isempty(argnames) && return argnames
return argnames[1:m.nargs]
end
``````

and then

``````ms = collect(methods(f))
method_argnames(last(ms))[2:end]
``````

you’ll get

``````3-element Array{Symbol,1}:
:x
:y
:z
``````
7 Likes

This solution doesn’t seem to work when using keyword arguments. Any suggestions?

The procedure in Get the argument names of an function - #3 by tim.holy still works; just stepping through to see how Julia does something is a useful skill for many questions. You’ll discover `Base.kwarg_decl` that way.

``````julia> m = @which sum(rand(3))
sum(a::AbstractArray; dims, kw...) in Base at reducedim.jl:994

julia> Base.kwarg_decl(m)
2-element Vector{Symbol}:
:dims
Symbol("kw...")
``````
6 Likes

Suppose I have a function

`f(p1, p2=default)`

which internally creates and saves a file whose content also depends on the value of p2.

How can I dynamically name the saved file according to the value of p2?

As an example, I defined
`default1=10` and I call `f(50, default1)`,
or
`default1(x)=5*x` and call `f(50, default1(2))`

how do i save the file with the name “something_default1.ext”?

I’m curious to know if and how such a thing can be done anyway, although it would be helpful to know a different way around the problem.