How to get the variable numbers for a julia function

I have a function called f for example.

function f(x1,x2,x3)
x1+x2*x3
end

How can get the number of variable of this function? For this example it should return 3.

2 Likes

You can do something like this:

julia> function f(args...)
           return length(args)
       end
f (generic function with 1 method)

julia> f(1,2,3)
3
3 Likes

What are you trying to accomplish? The analogue of nargin in Matlab in Julia is to define multiple methods (or optional/keyword arguments).

5 Likes

No. How to use the “accomplish”? I tried

accomplish(f)

But it seems not works. By the way, the “nargin” in Matlab does works.

He’s asking what you are trying to do. There is no accomplish function.

In Matlab nargin is an important function that you need to use all the time to figure out what inputs you have. In Julia you don’t need this at all.

Edit: I meant to reply to @gangchern

6 Likes

Matlab:

function ret = f(x1,x2)
    if nargin == 1
        ret = x1;
    elseif nargin == 2
        ret = x1+x2;
    end
end

and then:

>> f(2)

ans =

     2

>> f(2,2)

ans =

     4

In Julia:

julia> f(x1) = x1
f (generic function with 1 method)

julia> f(x1,x2) = x1+x2
f (generic function with 2 methods)

julia> f(2)
2

julia> f(2,2)
4
4 Likes

There’s also optioinal argument and keyword argument combining with dispatch usally cover most of the cases I need to deal with variadic functions.

And if all else failed, you can still declare the function as variadic which @mbaz mentioned in the very first reply already…

And if you want to figure out how many argument a function can accept from outside the function, then no that’s not a property of a function and you generally should not rely on that.

Unless it’s for debugging, in which case you can just iterate through the methods.

3 Likes

I don’t think you can do that in Matlab either.

Thanks,
This code is useful for me. Perhaps Julia do not have inherit method to get the number of variables of a function. As other people replied, it is not necessary for Julia.

To add to the excellent answers above: strictly speaking functions (eg f) don’t have an argument list, methods (eg f(::Any, ::Any, ::Any) do. The distinction between the two is crucial to using Julia efficiently.

Also, unless you are debugging or doing something very advanced, trying to recover this meta-information is usually a sign that the code is not well-designed for Julia.

7 Likes

Thank :+1:

Hi @gangchern!

I also had this question, and @Tamas_Papp’s answer put two and two together for me, haha.

Thanks for asking it.

Also, you should mark his answer as the solution so future enquirers will find it easier. :slightly_smiling_face:

Just for completeness, there is a way to access the number of arguments of a particular Method:

f = (x,y) -> x + y
first(methods(f)).nargs  - 1

This is used nicely in the LinearMaps.jl package that certainly qualifies as “something very advanced” as @Tamas_Papp said…
I don’t understand why the -1 is needed but it works…
But this is probably not what most Matlab users want when they search for nargin

1 Like

Complementing even more, I would directly translate the given Matlab example

to

julia> function f(x1, x2 = nothing)
           if x2 === nothing
               return x1
           else
               return x1 + x2
           end
       end
f (generic function with 2 methods)

julia> f(2)
2

julia> f(2, 2)
4
2 Likes

This might be a typo, but: Matlab = Matrix Laboratory.

It was a typo. Corrected.

Again, you really don’t want to do this. This looks like an XY problem, applying the Matlab solution to Julia, where there are more idiomatic approaches, eg

  1. for a vararg like f(args...), you just want length(args),

  2. for optional arguments, just do that, like @Henrique_Becker shows above,

  3. for the Matlab-style switch nargin, you want to define separate methods,

  4. Matlab’s nargin(f) really does not make sense in Julia because of multiple dispatch,

  5. in the remaining 0.1% cases if you are writing code introspection tools, you know what you are doing and need the internals.

6 Likes

Somehow one has to reach that point where “you know”, and searching forums like this can be helpful. The manual itself is very brief about what methods can do…

I think you misunderstand the context: most users never need to learn about internals and introspection of the methods table, so they don’t have to reach that point. In fact, using methods in regular code is an anti-pattern; it’s for interactive exploration.

If one really, really needs to know these details, they are mostly in the devdocs. Putting them into the manual per se would be misleading.

2 Likes