Julia supports keyword arguments in function calls but the keyword names must be entirely specified, even when there is no possibility of ambiguity.
In order to improve code readability, and speed up interactive usage on the REPL, it may be useful to use abbreviated names in function calls while maintaining full descriptive names in the function definitions. This packages provide such functionality through the @AbbrvKW
macro.
The idea for this macro came out from a post in the Usage forum. Hopefully, this functionality will be included as a native feature in future versions of Julia.
You may install this package typing:
Pkg.add("AbbrvKW")
in the Julia REPL.
Consider the following function:
function Foo(; Keyword1::Int=1, AnotherKeyword::Float64=2.0, StillAnotherOne=3, KeyString::String="bar")
@show Keyword1
@show AnotherKeyword
@show StillAnotherOne
@show KeyString
end
The only way to use the keywords is to type their entire names, resulting in very long code lines, i.e.:
Foo(Keyword1=10, AnotherKeyword=20.0, StillAnotherOne=30, KeyString="baz")
By processing the Foo
function through the @AbbrvKW
macro you may use abbreviated keywords, as long as the provided names allow complete disambiguation:
using AbbrvKW
@AbbrvKW function Foo(; Keyword1::Int=1, AnotherKeyword::Float64=2.0, StillAnotherOne=3, KeyString::String="bar")
@show Keyword1
@show AnotherKeyword
@show StillAnotherOne
@show KeyString
end
Foo(Keyw=10, A=20.0, S=30, KeyS="baz") # <-- Much shorter, isn't it?
The generated code also checks for unrecognized keyword, and raise an error in case they are found. If you wish to catch further keywords (and avoid raising an exception) simply add a symbol with a splat at the end of the keywords, e.g.:
@AbbrvKW function Foo(; Keyword1::Int=1, AnotherKeyword::Float64=2.0, StillAnotherOne=3, KeyString::String="bar", kw...)
To use the macro simply prepend @AbbrvKW
to the function
keyword. The macro will read the list of keywords and add code at the beginning of the function to handle keyword abbreviations. If the types are specified in the function definition the generated code will also typeassert
the keywords.
The @macroexpand
macro can be used to show the code generated by the @AbbrvKW
macro, i.e.:
julia> @macroexpand @AbbrvKW function Foo(;Keyword::Float64=1., verboseLevel::Union{Void,Int}=nothing)
println("Keyword: ", Keyword)
if verboseLevel != nothing
println("New verbosity level: ", verboseLevel)
end
end
:(function Foo(; Keyword::Float64=1.0, verboseLevel::Union{Void, Int}=nothing, _abbrvkw_...)
begin
_ii_ = 1
while _ii_ <= length(_abbrvkw_)
if (_abbrvkw_[_ii_])[1] in (:K, :Ke, :Key, :Keyw, :Keywo, :Keywor)
typeassert((_abbrvkw_[_ii_])[2], Float64)
Keyword = (_abbrvkw_[_ii_])[2]
deleteat!(_abbrvkw_, _ii_)
continue
end
if (_abbrvkw_[_ii_])[1] in (:v, :ve, :ver, :verb, :verbo, :verbos, :verbose, :verboseL, :verboseLe, :verboseLev, :verboseLeve)
typeassert((_abbrvkw_[_ii_])[2], Union{Void, Int})
verboseLevel = (_abbrvkw_[_ii_])[2]
deleteat!(_abbrvkw_, _ii_)
continue
end
_ii_ += 1
end
_ii_ = nothing
if length(_abbrvkw_) != 0
error("Unrecognized keyword abbreviation(s): " * string(_abbrvkw_))
end
_abbrvkw_ = nothing
end
println("Keyword: ", Keyword)
if verboseLevel != nothing
println("New verbosity level: ", verboseLevel)
end
end)
08/21/2017
over 5 years ago
19 commits