I can define a function
that handles Integer
s:
function twice(a::Int64) a + a end
This function cannot handle Float
s. If I want that, I need to define another method:
function twice(a::Float64) a + a end
But wait, this looks exactly the same, apart from the type definition. So, when I dream at night, there is a possibility to create such method definitions (everything identical apart from the type/combination of types) with a... macro maybe? Something like
@create_all_methods ("twice(a::$type ) a + a end", ["Int64", "Float64"])
Is this possible and if so, how?
Does the question maybe make no sense at all, because there is no situation where function twice(a) a + a end
wouldn't achieve the exact same thing anyway?
Thanks for your help in advance.
There are multiple ways to achieve that. The easiest would be to just omit the type of a
T then you methodn would look like:
function twice(a) a + a end
This is equivalent to
function twice(a::Any) a + a end
But maybe you don't want to define this for all types, or you already have another definition for twice(a::Any)
, so you could restrict your definition to the common supertype of Int64
and Float64
. This common supertype can be found with typejoin(Float64, Int64)
and yields the result Real
, so your definition would now be
function twice(a::Real) a + a end
This also creates a method for other subtypes of Real
such asa::Int32
, so if you really want the method only for Int64
and Float64
you can create a union type. Then the method would look like
function twice(a::Union{Int64, Float64}) a + a end
Finally, it is indeed possible to achieve what you wanted to achieve with your macro. It does not make sense in this case, but either the function eval
or the macro @eval
is often used in more complicated cases. Your code could then look like
for T in (Int64, Float64)
@eval function twice(a::$T) a + a end
end
If you you just started learning Julia, I would not advice to use eval
, as there are some dangers/anti-patterns associated with the usage of eval
.
A straightforward way of creating methods for two or more input types is to use Union
:
twice(a::Union{T1, T2, T3}) = a + a
where T1
, T2
, T3
, ect. are concrete types, such as Int
or Float64
.
More commonly, you would define it for some abstract supertype instead, for example
twice(a::Number) = a + a
But most of the time, you should just start by defining a generic function
twice(a) = a + a
and then add types when you find that it becomes necessary. Most of the time it isn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With