Using kwargs and non kwargs in a function call

Hi al,

I am new at programming in Julia, but I am struggling to implement and call a function in a particular way, which I was using a lot in Python. I have a function like:

function f(x, y=1, z=3; kwargs...)
    return x + y + z
end

however if I call it as f(5,6,z=10), it returns 14 as the ‘z=10’ is ignored and the default value is used. If I change the function having the semicolon after ‘x’, I still get the same results. What should I change to get 21 if I call it as f(5,6,z=10).

Put the semicolon before z.

1 Like

Hi Kristoffer,
Thanks and that actually solves it for this particular case but my question would be how to do it more generally (but I know I did not formulate it that way).

Let’s suppose I have more inputs and I am calling the function in many different ways:


function f(x, y=1, z=1, w=1, q=1, kwargs...)
    return x + y + z + w + q
end

f(0,y=2,z=2,w=2,q=2)
f(0,2,z=2,w=2,q=2)
f(0,2,2,w=2,q=2)
f(0,2,2,2,q=2)
f(0,2,2,2,2)

What should I do to have “8” as output for all the above calls?

Unlike Python, Julia makes a distinction between positional and keyword arguments. You can’t pass the same argument either through position or through name. In particular, positional arguments participate in dispatch, selecting the specific method invoked, and keyword arguments do not.

However, if you have only one method, you can emulate this with something like

f(x, _y=1; y=_y) = (x,y)

or, if you want to disallow calls like f(1,2,y=2)

function f(x, _y=nothing; y=nothing)
    if isnothing(_y) && isnothing(y)
        y = 1
    elseif !isnothing(_y) && !isnothing(y)
        error("two values assigned to y")
    else
        y = something(y,_y)
    end
    (x,y)
end

You can also dispatch on the types of (x,y) using f(x, _y=1; y=_y) = _f(x,y) and doing the dispatch in _f.

2 Likes

There is a discussion about this here: Allow use of named-argument syntax for positional arguments? - #21 by DNF

In my opinion allowing this would be a bad thing in general.

1 Like

Thank you for the quick help!