4 Function method multiple dispatch

4 Function method multiple dispatch

Functions and methods

function

Function definition

function f1(x,y)
    x + y # can be without return, of course it can also be written as return x + y
end
>>f (generic function with 1 method)
f(1,2)
>>3

The last line of the function does not need to add return, return is generally used when returning in the middle of the function. Because Julia’s code is all expressions (which will be discussed in the next section of metaprogramming), expressions have return values, either nothing, or something else, so the last line of the function is the return value by default, no need to add return; If a function does not want to return a value, just write it in the last line nothing.

You can specify the type of function output

function g(x, y)::Int8
           return x * y
end
typeof(g(2,3))
>>Int8

Symbols can also be used as functions

+(1,2,3)
>>6
f2 = +
f2(1,2,3)
>>6

Add a description to the function

"simple add function"
function funcAdd(x, y)
    x + y
end

Use @doc funcAddcan see comments before the function, if the function is defined in the REPL, you can helpview the function mode instructions

Anonymous function

map(x->x*2 + 1, [1,2,3,4])
>>4-element Array{Int64,1}:
 3
 5
 7
 9

Multiple return values

function f3(x,y)
    x+y, xy
end
f3(3,4)    
>>(7,-1) #Returned is a tuple
minVal(x,y) = (x <y)? x: y;

variable parameter

function f4(x...)
    r1 = length(x)
    r2 = x[r1]
    return r1,r2
end
println(f4(4,6,9))
>>(3,9)
println(f(11,15,(18,20)))
>>(3, (18,20))

Default parameter keyword parameter

function f5(x,y=1)
   return x + y
end
f5(3)
f5(5,6)
f5(x=7,y=8)

function f6(x;y,z=3)
   return x + y + z
end
f6(3,y=5)
f6(4,y=3,z=8)

Although the parameter type Julia is a dynamic language, the parameter type can be specified when the function is defined

function f7(x::Int8)
    x + 3
end
f7(Int8(10))

Other ways to use functions

map

function funcAbs(x)
    x >=0? x: -x
end
map(funcAbs, -3:3)

reduce

fucntion add(x, y)
    x + y
end
reduce(add, 1:10)
>>55
reduce(+, 1:10)
>>55

|>Operator, very intuitive for the order of operations

"abcde" |> uppercase
[i for i in 1:5] |> join

Of course, there are simpler and more flexible ways to define functions in Julia

f8(x::Int64,y::Int64) = 2*x + y
f8(4,3)
>>11

Seeing this, do you like Julia more! It is so concise and clear.

method

The difference between functions and methods

The same function can have different methods, such as addition function, which can realize integer addition, floating-point number addition and complex number addition, etc. They all realize the addition function, that is, they are the same function, but their implementation methods are different. Understand the overloading in C++. You can see on the REPL that there are several ways to define the function. Julia will choose the more specialized method.

function f9(x::Int64, y::Int64)
    x + y   
end
>>f9 (generic function with 1 method)

Indicates that the function has only one method

If we define another f9, the parameter type is Float64

function f9(x::Float64,y::Float64)
    x + y   
end
>>f9 (generic function with 2 methods)

At this time, when we execute the f(2,3)compiler, it will automatically choose a more dedicated method to execute, which is the first method.

We can also directly enter +the number of ways to see the plus sign (also a function)

+
>>+ (generic function with 170 methods)

You can use methods(f9)the specific method to see f9

But if neither method is more specialized, there will be differences.

g(x::Int64, y) = 2x + y
g(x, y::Int64) = x + 2y
g(2,3.0)
>>7.0
g(2.0,3)
>>8.0

But if it is g(2,3), the two methods no more dedicated, then it will report error, it is to define a more specific solutions: g(x::Int64, y::Int64).

Parametric method

We first define a simple method, for any input, the result isfalse

f10(x,y) = false
f10(1,2)
>>false

Add another method

f10(x::T, y::T) where {T} = true
f10(1,2)
>>true
f10(1,2.1)
>>false

The second method means that when the two parameters are of the same type, return true

Of course, this way can also operate on the matrix

f11(v::Vector{T}, x::T) where {T} = [v..., x]
f11([1,2,3],4)
>>4-element Array{Int64,1}:
 1
 2
 3
 4
f11([1,2,3],4.2)
>>ERROR: MethodError

You can also constrain subtype parameters

f12(x::T, y::T) where {T<:Number} = true

Multiple dispatch

Dispatching refers to selecting the corresponding method according to the type of the variable, and single dispatching refers to selecting the method according to the type of the first parameter.

Let's take an example in Python. Since Python does not know the parameter types when defining functions, there is generally no single-dispatch; however, Python provides single-dispatch modifiers that can realize the single-dispatch function.

from functools import singledispatch

@singledispatch
def func(arg, verbose=False):
    print('initial...\n')

@func.register(int)
def _(arg, verbose=False):
    print(arg)

func(1)
>>1
func(2.3)
>>initial...

It can be seen that the result of the function func() is only related to the type of the first parameter, and has nothing to do with the following parameters. This is single dispatch.

Using all the parameters of the function instead of just the first one to decide which method to call is called multiple dispatch. Multi-dispatch is particularly useful for mathematical codes. The concept of artificially treating an operation as one parameter is stronger than all other parameters is almost meaningless to mathematical code: the addition operation pair in x + y Is the degree of belonging of x stronger than that of y? The realization of a mathematical operator is generally based on the types of all its parameters. Even out of mathematical operations, multiple assignment is a powerful and convenient paradigm for structuring and organizing programs.

Use of optimization methods

  • Dispatched based on only one parameter

Julia is a multiple dispatch mode, so what if we want to dispatch only based on the first parameter when defining a method? We can use the "name cascade" method to do the assignment internally. For example, we can use the following method:

f(x::A, y) = _fA(x, y)
f(x::B, y) = _fB(x, y)

In this way, for the function f(), it can be dispatched based only on the first parameter.

Reference: https://cloud.tencent.com/developer/article/1653095 4 Function method multiple dispatch-Cloud+Community-Tencent Cloud