Till now in functions you have seen functions where arguments are positional, say you define a function like this:
function sub(a, b) return a - b end
here it’s always
b, the second argument that will get subtracted from
a, the first argument. Like when you call
sub(5, 3) that you will get 2 as output, but what if I want to do something like this
sub(b = 20, a = 70), where I expect output to be 70 minus 20 that is 50, no that isn’t possible till now. Now let’s see how to do these kind of stuff.
Code the function below in your Jupyter lab and let’s see how it works.
function increment(number = 0; inc = 0, dec = 0) number + inc - dec end
increment (generic function with 4 methods)
First, we call just
increment() as shown below:
in this case the
dec defaults to
0. And hence we get the output as
0. Now let’s call it with just one argument as shown:
1 is passed as positional argument and hence
function increment(number = 0; inc = 0, dec = 0) becomes
1 and hence
1 is returned.
Now let’s see the code below:
increment(2, inc = 5)
and this code:
increment(12, dec = 8)
dec are not passed as positional argument, but they were named as
increment(2, inc = 5) and
increment(12, dec = 8), yet Julia seems to have compute the results correctly. If these were positional then
8 should have been pass to
inc within the function when we call
increment(12, dec = 8).
In the example below we give both
dec as named arguments to the function:
increment(10, inc = 5, dec = 7)
So how Julia knows
dec are named arguments but not positional. If you see the function definition
function increment(number = 0; inc = 0, dec = 0), you can see we have place
inc = 0 and
dec = 0 after a semicolon
;, that’s a hint to Julia that these arguments could be named arguments.
Just because we have said that they are named arguments, it does not mean that they have lost their positional status. We can very well call the
increment() function as shown below, where every argument preserves its positional properties.
increment(10, 5, 7)
Now see how I have coded the function
printline5() below, where all arguments are placed after the semicolon
; and are hence named arguments, and they have default values too:
function printline5(;length = 50, character = '*') println(character ^ length) end
printline5 (generic function with 1 method)
So if I want a line of variable length I can call as shown:
printline5(length = 7)
If I want a line of different character, I can call like this:
printline5(character = '@')
Let’s say I want a line of my preferred length and the character of my choice, I can call like this:
printline5(length = 7, character = '!')
And I can call it with out any argument at all, in the case below it takes default
But since all are placed behind a semicolon, I notice that they have lost their positional status in this case:
MethodError: no method matching printline5(::Int64, ::Char) Stacktrace:  top-level scope at In:1  include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091  execute_code(::String, ::String) at /home/karthikeyan/.julia/packages/IJulia/a1SNk/src/execute_request.jl:27  execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/karthikeyan/.julia/packages/IJulia/a1SNk/src/execute_request.jl:86  #invokelatest#1 at ./essentials.jl:710 [inlined]  invokelatest at ./essentials.jl:709 [inlined]  eventloop(::ZMQ.Socket) at /home/karthikeyan/.julia/packages/IJulia/a1SNk/src/eventloop.jl:8  (::IJulia.var"#15#18")() at ./task.jl:356
Looks like you need one positional argument before the semicolon
; for named argument to preserve their positional properties.
You can get the Jupyter notebook file for this blog here https://gitlab.com/data-science-with-julia/code/-/blob/master/functions.ipynb.