Trying to get the arity of a function

I written a function to return the arity of a given function:

function arity(f)
if f == + return 2 # arithmetic functions
if f == - return 2
if f == * return 2
if f == / return 2
if f == ^ return 2
if f == % return 2

if f == sin return 1				# trig functions
if f == cos return 1
if f == tan return 1

end

It works fine for +, -, sin, cos, and tan, but fails for the others with the error message:
ERROR: syntax: “*” is not a unary operator.

Why doesn’t this work for all the included functions?

Try adding : before the troublesome symbols.

NB: and back-ticks in your post in the lines before function and after end

That works, many thanks!

In julia, a function does not have a fixed arity, only methods do. I believe you can get the arity of a method like so

julia> methods(sin).ms[1].nargs-1
1

julia> methods(+).ms[1].nargs-1
2

Note the indexing [1] picking the first out of many methods in the method list. The -1 is required since I believe the function itself counts as one argument.

3 Likes

Many thanks for thid information!

1 Like

If you are happy with the manual-ness of the first solution you can use dispatch for it:

arity(::typeof(+)) = 2
arity(::typeof(sin)) = 1
...

julia> arity(+)
2

Very interesting!

arity(f) = extrema(m -> m.nargs, methods(f)) .- 1
findarity(f, k) = (ms = collect(methods(f)); ms[findall(m -> m.nargs - 1 == k, ms)])

arity(+)

(1, 5)

Why is the maximum of the arities of + equal to 5? :flushed:

findarity(+, 5)

2-element Vector{Method}:

  • +(a:: BigInt , b:: BigInt , c:: BigInt , d:: BigInt , e:: BigInt ) in Base.GMP at gmp.jl:521
  • +(a:: BigFloat , b:: BigFloat , c:: BigFloat , d:: BigFloat , e:: BigFloat ) in Base.MPFR at mpfr.jl:549
julia> +(1,2,3,4,5)
15

+ can take many arguments. The reason might be that intermediate allocations can be avoided for +(A,B,C) where the arguments are matrices.