Skip to content

Commit 87280a4

Browse files
committed
Implement keyword aliases
Fixes #2.
1 parent 3cd371c commit 87280a4

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

src/KeywordDispatch.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Designate a function signature `sig` that should dispatch on keyword arguments.
110110
function can also be provided, in which case _all_ calls to that function are will
111111
dispatch to keyword methods.
112112
113-
Note that no keywords should appear in `sig` signatures.
113+
It is possible to specify keyword aliases by specifying `from => to` pairs in the keyword position.
114114
115115
The optional `methods` argument allows a block of keyword methods specified as anonymous
116116
functions. To define additional keyword methods, use the [`@kwmethod`](@ref) macro.
@@ -131,6 +131,8 @@ end
131131
# @kwdispatch f(x)
132132
# @kwmethod f(x;a) = x+a
133133
# @kwmethod f(x;b) = x-b
134+
135+
@kwdispatch f(; alpha=>α) # specifies alpha as an alias to α
134136
```
135137
"""
136138
macro kwdispatch(fexpr,methods=nothing)
@@ -143,10 +145,19 @@ macro kwdispatch(fexpr,methods=nothing)
143145

144146
@assert fcall isa Expr && fcall.head == :call
145147

148+
rename_expr = :(kw)
149+
146150
f = fcall.args[1]
147151
posargs = fcall.args[2:end]
148152
if length(posargs) >= 1 && posargs[1] isa Expr && posargs[1].head == :parameters
149-
error("keyword arguments should only appear in @kwdispatch expressions")
153+
parameters = popfirst!(posargs)
154+
for p in parameters.args
155+
if p isa Expr && p.head == :call && p.args[1] == :(=>)
156+
rename_expr = :(kw == $(QuoteNode(p.args[2])) ? $(QuoteNode(p.args[3])) : $rename_expr)
157+
else
158+
error("Only renames (from => to) are allowed in keyword position of `@kwdispatch`")
159+
end
160+
end
150161
end
151162
f = argmeth(f)
152163

@@ -160,8 +171,11 @@ macro kwdispatch(fexpr,methods=nothing)
160171
ff = esc(argsym(f))
161172

162173
quote
163-
$(wrap_where(:($(esc(f))($(esc.(posargs_method)...); kwargs...)), wherestack)) =
164-
KeywordDispatch.kwcall(ntsort(kwargs.data), $ff, $(esc.(argsym.(posargs_method))...))
174+
$(wrap_where(:($(esc(f))($(esc.(posargs_method)...); kwargs...)), wherestack)) = begin
175+
N = map(kw -> $rename_expr, propertynames(kwargs.data))
176+
nt = NamedTuple{N}(Tuple(kwargs.data))
177+
KeywordDispatch.kwcall(ntsort(nt), $ff, $(esc.(argsym.(posargs_method))...))
178+
end
165179
$(generate_kwmethods(methods, f, posargs, wherestack))
166180
end
167181
end

test/runtests.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ struct Baz{T}
214214
w::T
215215
end
216216

217-
@testset "kwdispatch extra arg" begin
217+
@testset "kwdispatch subtype extra arg" begin
218218
global Baz
219219

220220
@kwdispatch (::Type{B})() where {B<:Baz} begin
@@ -234,3 +234,20 @@ end
234234
@test Baz{Int}(z=4) == Baz{Int}(2)
235235
@test Baz{Float64}(z=4) == Baz{Float64}(2.0)
236236
end
237+
238+
239+
@testset "kw rename" begin
240+
@kwdispatch f(;alpha => α, beta => β)
241+
242+
@kwmethod f(;α) = 1
243+
@kwmethod f(;β) = 2
244+
@kwmethod f(;α,β) = 3
245+
246+
@test f=0) == 1
247+
@test f(alpha=0) == 1
248+
249+
@test f=0) == 2
250+
@test f(beta=0) == 2
251+
252+
@test f(alpha=0,beta=0) == 3
253+
end

0 commit comments

Comments
 (0)