Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass keywords and keyword variable values to a function via Tuples

Tags:

julia

You can easily pass "normal" (i.e. non-keyword) variable values to a function via a Tuple with an ellipsis, like e.g.:

julia> f(x, y, z) = x + y + z;

julia> f(0, 1, 2)
3

julia> varvalues = 0, 1, 2
(0,1,2)

julia> f(varvalues...)
3

But for keyword variables, how do you pass both the keywords and the corresponding variable values via variables? Like e.g. (forgive the silly example):

julia> function g(x, y, z; operation = "add", format = "number")
           operation == "add"   && format == "number" && return        x + y + z
           operation == "add"   && format == "string" && return string(x + y + z)
           operation == "times" && format == "number" && return        x * y * z
           operation == "times" && format == "string" && return string(x * y * z)
       end;         # yep, I know this not type-stable

julia> g(0, 1, 2, operation = "times", format = "string")
"0"

julia> g(varvalues..., operation = "times", format = "string")    # varvalues = (0,1,2)
"0"

So I would like to define two variables, analogous to varvalues above: keywords with the keywords and keywordvarvalues with the corresponding variable values, that can be passed to function g. Something like this, but that works:

julia> keywords = :operation, :format
(:operation,:format)

julia> keywordvarvalues = "times", "string"
("times","string")

julia> g(varvalues..., keywords... = keywordvarvalues...)
ERROR: MethodError: no method matching broadcast!...

I suppose I can always compose this String from keywords and keywordvarvalues:

expressionstring = """g(varvalues..., operation = "times", format = "string")"""

and then parse-eval it, but that's prolly bad practice, no?

like image 864
Felipe Jiménez Avatar asked Dec 05 '16 09:12

Felipe Jiménez


2 Answers

This works:

julia> keywords = :operation, :format
(:operation,:format)

julia> keywordvarvalues = 10, 20
(10,20)

julia> g(; operation=1, format=2) = (operation, format)
g (generic function with 1 method)

julia> g(; zip(keywords, keywordvarvalues)...)
(10,20)
like image 193
Milan Bouchet-Valat Avatar answered Oct 21 '22 02:10

Milan Bouchet-Valat


You can also use dictionaries:

julia> g(; keywords...) = keywords

julia> g(a=3, b=4)
2-element Array{Any,1}:
 (:a,3)
 (:b,4)

julia> d = Dict(:c=>5, :d=>6)
Dict{Symbol,Int64} with 2 entries:
  :c => 5
  :d => 6

julia> g(; d...)
2-element Array{Any,1}:
 (:c,5)
 (:d,6)
like image 1
David P. Sanders Avatar answered Oct 21 '22 01:10

David P. Sanders