Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: Is it possible to pass a dictionary of parameters to a function?

I have a dictionary of function arguments that I want to pass to a function. For example:

function test_function(foo::Int, bar::String)
    #...
end

params = Dict(
    "foo" => 1,
    "bar" => "baz"
)

In Python, I could pass all parameters as kwargs like this:

def test_function(foo: int, bar: str):
    #...

params = {
    "foo": 1
    "bar": "baz"
}

test_function(**params)

But when I try params..., I get the following error:

julia> test_function(params...)
ERROR: MethodError: no method matching test_function(::Pair{String,Any}, ::Pair{String,Any})

Is there a way to do anything similar in Julia?

like image 562
A Poor Avatar asked May 07 '21 02:05

A Poor


People also ask

Can I pass a dictionary as Kwargs?

Passing Dictionary as an argument In Python, everything is an object, so the dictionary can be passed as an argument to a function like other variables are passed. “ kwargs ” stands for keyword arguments.

Is Julia pass by value?

In Julia, values are passed and assigned by reference.

What is :: In Julia?

A return type can be specified in the function declaration using the :: operator. This converts the return value to the specified type. This function will always return an Int8 regardless of the types of x and y .

What is the type of a function in Julia?

Function is an abstract type. So for example Vector{Function} is like a Vector{Any} , or Vector{Integer} : Julia just can't infer the results.

How does Julia handle type parameters?

As a heuristic, Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg. Julia will always specialize when the argument is used within the method, but not if the argument is just passed through to another function.

How to access elements of a dictionary in Julia?

Julia provides a pre-defined function to access elements of a Dictionary known as get () function. This function takes 3 arguments: dictionary name, key, and a default value to print if the key is not found. Dictionaries in Julia allow accessing all the keys and all the values at once.

How do function arguments work in Julia?

Julia function arguments follow a convention sometimes called "pass-by-sharing", which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values.

What is the difference between a method and a function in Julia?

In simple words, whenever the function will be called with arguments of a new type, the Julia compiler will generate a separate version of that function. On the other hand, a function for a specific combination of arguments types is called a Method.


Video Answer


2 Answers

Julia makes a clear distinction between positional arguments and keyword arguments. To clarify the distinction, you can separate positional arguments from keyword arguments with a semicolon. You can unpack objects into positional arguments or keyword arguments using ..., which is referred to as the splatting operator.

If you want to unpack an object into keyword arguments, it needs to be an iterator of pairs or tuples. If you unpack an object into positional arguments, the unpacked element types need to match one of the methods of the function.

Here's an example:

function foo(x, y; a=1, b=2)
    x + y + a + b
end

t = (1, 2)
d = Dict(:a => 3, :b => 4)
julia> foo(t... ; d...) 
10

However, note that the keys in the dictionary (or iterator of pairs/tuples) must be symbols in order for unpacking into keyword arguments to work:

julia> e = Dict("a" => 3, "b" => 4);

julia> foo(t... ; e...)
ERROR: MethodError: Cannot `convert` an object of type String
to an object of type Symbol

For more info, see the Varargs and Keyword Arguments sections of the manual.

like image 80
Cameron Bieganek Avatar answered Oct 17 '22 07:10

Cameron Bieganek


EDIT: Oops posted this just after Cameron's answer. I'll leave it here in case it is helpful, but honestly, it says pretty much the same thing as his answer :-)

In Julia, the generic function signature is f(args ; kwargs). The names of the regular input arguments args don't really matter, it is the order in which they appear in the function signature that is important. In contrast, for the keyword arguments kwargs it the name that matters, and the order is not important.

The final piece of information we need is that for either args or kwargs, the splatting operator ... separates out the elements of the container being splatted into individual arguments for the function signature.

So, let's apply this all to your example. Consider the following two functions:

function f1(foo::Int, bar::String)::String
    return "$(foo) --> $(bar)"
end
function f2( ; foo::Int=0, bar::String="nil")::String
    return "$(foo) --> $(bar)"
end

The first function only has args while the second function only has kwargs. In the case of the first function, names don't matter since we're dealing with args, so in order to splat a container we would use just use a vector or tuple, e.g.:

params = [1, "baz"]
f1(params...)

The second function only has kwargs, and Julia expects to see these expressed as the type Pair{Symbol,T} for some T<:Any. So, if we construct our dictionary to map the name of the keyword argument (expressed as a Symbol) to the value, then the splatting operator will splat each entry of the dictionary into the function signature like so:

params = Dict(:foo=>1, :bar=>"baz")
f2(; params...)

Note that I had to use ; in the function call to indicate there were no args, only kwargs.

And of course, if needed, you can have both at the same time, e.g. f3(vectorofargs... ; dictofargs...).

like image 4
Colin T Bowers Avatar answered Oct 17 '22 06:10

Colin T Bowers