Optional Keyword arguments

I am exploring how to use optional keyword arguments. I understand the syntax of giving the argument a default value in the function call statement. However, it must be possible to give default values without putting the argument in the function statement, otherwise plot and many other functions would not work. What are the mechanics of doing this.

A minimum working example is:

struct Timelimits
    st::Float64
    fin::Float64
end

function g(ti::AbstractVector, tl::Timelimits = Timelimits(ti[begin],ti[end]))
    if ~@isdefined(tl)
        tl = Timelimits(ti[begin], ti[end])
        println("Executing if statement")
    end

    #rest of function body
    println("Start is $(tl.st) and finish is $(tl.fin)")
end

julia> g(0.0:10.0)
Start is 0.0 and finish is 10.0

julia> g(0.0:10.0, Timelimits(1.0, 5.0))
Start is 1.0 and finish is 5.0

As a by the way, if I change the comma to a semi-colon in the function line I get an error which I then rectify by passing in a variable.

function g(ti::AbstractVector; tl::Timelimits = Timelimits(ti[begin],ti[end]))

julia> g(0.0:10.0; Timelimits(1.0, 5.0))
ERROR: syntax: invalid keyword argument syntax "Timelimits(1, 5)" around REPL[29]:1
Stacktrace:
 [1] top-level scope
   @ REPL[29]:1

julia> tl = Timelimits(0.0, 100.0)
Timelimits(0.0, 100.0)

julia> g(0.0:10.0; tl)
Start is 0.0 and finish is 100.0

I am wondering how I can define the function g so that it can optionally accept the variable tl, and if tl is not given then it will go to the if statement to set tl?

Your first example definition uses a optional positional argument and not a keyword argument. Your second example definition uses a keyword argument named tl. In Julia, when you call a function with a keyword argument you must use this name, as you discovered (either g(x; tl=y) or g(x; tl) which is just a shorthand for g(x; tl=tl).

Now, to the question about defaults: A common way is to use nothing as a default, and check for that inside the function body, for example:

function g(ti::AbstractVector; tl = nothing) # or tl::Union{Timelimits,Nothing} = nothing
    if tl === nothing
        tl = Timelimits(ti[begin],ti[end])
    end
    # ...
end
3 Likes