Say I have a function, call it q
and it has multiple signatures:
q(a,b)
q(b)
...
And I have the relationship that p = 1 - q
Is there a simpler way to define this other than to list out the same set of signatures?
I.e. not do the following
p(a,b) = 1 - q(a,b)
p(b) = 1 - q(b)
...
I tried just saying p = 1 - q
but I get a MethodError: no method matching -(::Int64, ::typeof(q))
Also tried p() = 1 - q()
but that’s just defining a function with no arguments, not passing along a variable set to q
can you try this?
q(args...) = 1-p(args...)
tell me if it works, i will need this in some point in the future
1 Like
Alec_Loudenback:
I.e. not do the following
p(a,b) = 1 - q(a,b)
p(b) = 1 - q(b)
...
Why not? That looks like the right way to do it. Ideally, you expose an interface via a small set of functions, so this should not be cumbersome.
But as @longemen3000 suggested,
@inline p(args...) = 1 - q(args...)
should work fine.
1 Like
Yea, I might end up still defining it that way. I was curious because I’m trying to build out ActuarialScience.jl and there’s a lot of functions that are useful to export that have the same “name” but different dispatch/signatures (e.g. life annuities ) where often the different signatures really have a simpler relationship (like that in my original example.
Really just looking to build out my understanding of the different things I can do with Julia.
Question on your response though - in this case, what would @inline
do?
Alec_Loudenback:
what would @inline
do?
See the documentation, eg ?@inline
.
The other approach you could take is for the first signature of q
, wrap a
and b
in a struct. Something like:
struct MyType
a::SomeType
b::SomeType
end
q(b) = ...
q(ab::MyType) = ...
p(x) = 1 - q(x)
1 Like
Reviving this topic, as now I’m refactoring to use keyword arguments in some cases, but the splat doesn’t work in this case:
q(a,b) = 0.1
q(b) = 0.2
q(a,b;c=2) = 0.3
p(args...) = 1.0 - q(args...)
p(1,2) # 0.9
p(1) # 0.8
p(1,2,b=3) # function p does not accept keyword arguments
Out of curiosity, I tried to run these commands. For p(1,2) I get 0.7 instead of 0.9 once q(a,b;c=2) has been defined.
julia> q(a,b) = 0.1
q (generic function with 2 methods)
julia> q(b) = 0.2
q (generic function with 2 methods)
julia> q(a,b;c=2) = 0.3
q (generic function with 2 methods)
julia> p(args...) = 1.0 - q(args...)
p (generic function with 1 method)
julia> p(1,2) # 0.9
0.7
julia> p(1) # 0.8
0.8
julia> p(1,2)
0.7
p(args...; kwargs...) = 1.0 - q(args...; kwargs...)
2 Likes
I still get p(1,2) as 0.7 even after doing this.
julia> q(a,b) = 0.1
q (generic function with 1 method)
julia> q(b) = 0.2
q (generic function with 2 methods)
julia> q(a,b;c=2) = 0.3
q (generic function with 2 methods)
julia> p(args...;kwargs...) = 1.0 - q(args...;kwargs...)
p (generic function with 1 method)
julia> p(1,2)
0.7
julia> p(1,2,c=5)
0.7
q(a,b;c=2) = 0.3
overwrites q(a,b) = 0.1
, so that’s to be expected. I was just responding to @Alec_Loudenback .
@tkoolen : Thanks I did understand the same behaviour but was curious to know if there is way out.
Nope, because keyword arguments do not participate in dispatch.
2 Likes