# How to define a function with more than one optional arguments in Julia?

I am trying to understand the mechanism to define functions in Julia.
For example

``````function xyzpos(x, y, z=0)
println("\$x, \$y, \$z")
end
``````

Note that

``````xyzpos(1,2)
> 1, 2, 0
``````

and

``````xyzpos(1,2,z=3)
> 1, 2, 3
``````

Up to here, it’s ok. Now, note that

``````xyzpos(x,y=9,z=3)
> MethodError: no method matching xyzpos(::Int64; y=9, z=3)
``````

So, I’m trying to fix this with

``````function xyzpos2(x, y=0, z=0)
println("\$x, \$y, \$z")
end
``````

But, note that

``````xyzpos2(5,y=9,z=3)
> MethodError: no method matching xyzpos2(::Int64, ::Int64; y=9, z=3)
``````

I’m not understanding the logic of the mechanism when defining functions

Help

``````julia> xyzpos(x, y, z=0) = x,y,z
xyzpos (generic function with 2 methods)

julia> xyzpos(1,2,z=3)
ERROR: MethodError: no method matching xyzpos(::Int64, ::Int64; z=3)
Closest candidates are:
``````

this shouldn’t work, if you don’t have `;`, you simply don’t have keyword argument, so what you want is:

``````function xyzpos(; x, y, z=0)
println("\$x, \$y, \$z")
end
``````

notice the `;`

1 Like

For me, It works:

what Julia version are you on? that looks like an old bug or your kernel is in bad state (cell 410 and 411? can you restart kernel)

I think you’re confusing optional arguments with keyword arguments.

(In Python, these are essentially the same thing, but in Julia they are distinct because positional arguments are used for dispatch.)

2 Likes
``````julia> versioninfo()
Julia Version 1.6.4 Commit 35f0c911f4 (2021-11-19 03:54 UTC) Platform Info:
``````

You must have defined another method earlier that used a keyword `z`, e.g.:

``````julia> xyzpos(x, y; z=0) = "\$x, \$y and keyword \$z"
xyzpos (generic function with 1 method)

julia> xyzpos(x, y, z=0) = "\$x, \$y, \$z"
xyzpos (generic function with 2 methods)

julia> xyzpos(1,2,z=3)
"1, 2 and keyword 3"
``````

This is the peril of experimenting in a long-running session; you may have other method definitions lurking that you’ve forgotten about.

2 Likes
``````  | | |_| | | | (_| |  |  Version 1.6.4 (2021-11-19)
_/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> xyzpos(x, y, z=0) = x,y,z
xyzpos (generic function with 2 methods)

julia> xyzpos(1,2,z=3)
ERROR: MethodError: no method matching xyzpos(::Int64, ::Int64; z=3)
Closest candidates are:
xyzpos(::Any, ::Any) at REPL[1]:1 got unsupported keyword argument "z"
xyzpos(::Any, ::Any, ::Any) at REPL[1]:1 got unsupported keyword argument "z"
Stacktrace:
[1] top-level scope
@ REPL[2]:1
``````
1 Like

I restarted and it didn’t work. Thanks!

You may consider consulting the section “function arguments” of the course “Introduction to scientific programming and machine learning with Julia”:

1 Like

After “;” Why did you leave the y argument with no value and the z = 0 argument? I thought that after the “;” necessarily we had to put “y= some value”

no, if you put value it’s “optional keyword argument”, if not, it’s “keyword argument”

1 Like

From the manual:

If a keyword argument is not assigned a default value in the method definition, then it is required: an `UndefKeywordError` exception will be thrown if the caller does not assign it a value

(I actually added this feature in Julia 0.7.)

2 Likes

Basically arguments can be:

• Positional OR Keyword
• Optional OR Mandatory

Those are two distinct ways of classifying them, and they’re independent of one another:

Positional arguments - those that come before the `;` - can be either optional (given a default value) or mandatory.

Same for keyword arguments - ones after the `;` in the function definition - those can be optional or mandatory too.

1 Like