Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create multiple Methods automatically

Tags:

julia

I can define a function that handles Integers:

function twice(a::Int64) a + a end

This function cannot handle Floats. 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"])
  1. Is this possible and if so, how?

  2. 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.

like image 638
Georgery Avatar asked Dec 11 '22 00:12

Georgery


2 Answers

There are multiple ways to achieve that. The easiest would be to just omit the type of aT 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.

like image 186
Simon Schoelly Avatar answered Dec 28 '22 20:12

Simon Schoelly


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.

like image 42
DNF Avatar answered Dec 28 '22 21:12

DNF