In Ruby, I can require an argument both (1) appear, and (2) have a parameter name:
>> def f(x:)
>> x + 1
>> end
>> f()
ArgumentError: missing keyword: x
>> f(2)
ArgumentError: wrong number of arguments (given 1, expected 0)
>> f(x:7)
=> 8
That is, I have to pass the argument, and I have to supply the associated parameter name.
I can do the same in Python:
>>> def f(*, x):
... return x + 1
...
>>> f()
TypeError: f() missing 1 required keyword-only argument: 'x'
>>> f(3)
TypeError: f() takes 0 positional arguments but 1 was given
>>> f(x=7)
8
And, for good measure, even Swift can do this:
1> func f(x: Int) -> Int {return x + 1}
2> f()
error: missing argument for parameter 'x' in call
2> f(3)
error: missing argument label 'x:' in call
2> f(x:7)
$R0: Int = 8
But I cannot figure out how to do this in Julia. It seems that keyword arguments, as they are called, must take default parameters. Is this correct, or is there a way to simulate the Ruby and Python examples above?
In Julia 0.7 (which was the compatibility release with all 1.0 features), this ability was added PR #25830.
To specify a required keyword argument list it after the ;
but do not provide a default value:
julia> f(; x) = x + 1
f (generic function with 1 method)
julia> f(;x=3)
4
julia> f()
ERROR: UndefKeywordError: keyword argument x not assigned
This is correct. In julia you cannot have required keyword arguments. Key word arguments are a special type of optional argument -- one which is set by by name, rather than by position.
(Related to this: you cannot set a non-keyword argument by name -- which you can do in Python and C#.)
You can, as @amrods suggested ensure this at runtime.
I would do that with
function f(; x = nothing)
x===nothing && error("x not set.")
#...
end
That check will be optimized out, if they type of x
is known (inferred) at the caller, at compile type.
but it won't actually be enforced until run-time. You also could use @Fengyang very elegant way to achieve the same.
You could probably enforce this at compile time by replacing your function with a generated function. But it is an awful hack.