Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Julia function


May 14, 2021 Julia


Table of contents


Function

A function in Julia is an object that reflects a set of parameters into an object that returns a value, and Julia's function is not a purely mathematical function, and some functions can change or affect the global state of the program. The basic syntax of defining functions in Julia is:

function f(x,y)
  x + y
end

Functions can be refinedly defined in Julia. The above traditional declaration syntax is equivalent to the following compact "assignment form":

f(x,y) = x + y

For assignment forms, the function body is usually a single expression, but it can also be a composite expression (see Compound Expression for details). T his short, simple function definition is common in Julia. Short function syntax is relatively easy to enter and read.

Use parentheses to call functions:

julia> f(2,3)
5

Without parentheses, f expression points to a function object that can be passed as a value:

julia> g = f;

julia> g(2,3)
5

There are two ways to call a function: using a special operator syntax with a specific function name (see the function operator later), or using apply function:

julia> apply(f,2,3)
5

apply function regards the first argument as a function object and applies it to subsequent arguments.

Like variable names, function names can also use Unicode characters:

julia> ∑(x,y) = x + y
∑ (generic function with 1 method)

The argument pass behavior

The parameters of the Julia function follow the "pass-by-sharing" convention, which is not to pass a value, but rather to pass a reference. F unction parameters themselves are a bit like new variable bindings (the new location of reference values), but they refer to the same value as the value passed. Modifications to variable values, such as arrays, affect other functions.

return keyword

The value returned by a function is usually the value of the last expression in the function body. I n the last f the x + y In C and most command or function languages, the return keyword return to return as soon as the value of the expression is evaluated:

function g(x,y)
  return x * y
  x + y
end

Compare the following two functions:

f(x,y) = x + y

function g(x,y)
  return x * y
  x + y
end

julia> f(2,3)
5

julia> g(2,3)
6

In pure linear function bodies, such as g, you don't need return which does not evaluate x + y Y ou can x * y as the last expression of the function and omit return R eturn is useful only if other control return are involved. The following example calculates the length of the beveled edges of the right triangle, where the right-angled edges are x and y, to avoid overflow:

function hypot(x,y)
  x = abs(x)
  y = abs(y)
  if x > y
    r = y/x
    return x*sqrt(1+r*r)
  end
  if y == 0
    return zero(x)
  end
  r = x/y
  return y*sqrt(1+r*r)
end

The last line of return be omitted.

The function operator

In Julia, most operators are functions that support a specific syntax. && || T he exception to iso-short-circuit operations is that they are not functions, because short-circuited values count first the previous value and then the subsequent values. For function operators, you can enclose the list of arguments in parentheses, just like any other function, as an argument to a function operator:

julia> 1 + 2 + 3
6

julia> +(1,2,3)
6

The infix form is exactly the same as the function form, in fact, the former is internally resolved as the form of a function call. You can assign, pass, and pass + such * , and so on, just like any other function:

julia> f = +;

julia> f(1,2,3)
6

However, at this point f function does not support the suffix expression.

The operator of a special name

There are some expressions that call operators with special names:

The expression Call
[A B C ...] hcat
[A, B, C, ...] vcat
[A B; C D; ...] hvcat
A' ctranspose
A.' transpose
1:n colon
A[i] getindex
A[i]=x setindex!

These functions exist in Base.Operators module.

Anonymous function

A function in Julia is a class 1 object that can be assigned to a variable, can be called by a variable after it has been assigned, can be used as an argument and return value, and can even be constructed anonymously:

julia> x -> x^2 + 2x - 1
(anonymous function)

The example above constructs an anonymous function, enters an argument x, and returns the value of the polynthic x^2 plus 2x - 1. T he main function of an anonymous function is to pass it to a function that accepts other functions as arguments. The most classic example is map function, which applies the function to each value of the array and returns the result array:

julia> map(round, [1.2,3.5,1.7])
3-element Array{Float64,1}:
 1.0
 4.0
 2.0

map first argument to the map can be a non-anonymous function. In most cases, however, when such a function does not exist, anonymous functions can simply construct a single-purpose function object without the need for a name:

julia> map(x -> x^2 + 2x - 1, [1,3,-1])
3-element Array{Int64,1}:
  2
 14
 -2

Anonymous functions can (x,y,z)->2x+y-z T he non-parameter anonymous function is ()->3 Non-parameter anonymous functions can be "delayed" calculations, and when this is useful, the code is encapsulated into non-parameter f()

Multiple return values

Julia can simulate returning multiple values by returning multiple groups. H owever, multiple groups do not require parentheses to construct and destruct, thus creating the illusion that multiple values can be returned. The following example returns a pair of child values:

julia> function foo(a,b)
         a+b, a*b
       end;

If you call this function in an interactive session, but do not assign the return value, you will see that the multiple groups are returned:

julia> foo(2,3)
(5,6)

Julia supports simple multigroup "destructoring" to assign values to variables:

julia> x, y = foo(2,3);

julia> x
5

julia> y
6

You can also return via return

function foo(a,b)
  return a+b, a*b
end

This is the same as the foo result.

Variable parameter function

The list of arguments for a function can sometimes be convenient if it can be any number. T his function is called a "variable parameter" function and is short for "variable number of parameters". You can define variable parameter functions by following the ... after the last argument...

julia> bar(a,b,x...) = (a,b,x)
bar (generic function with 1 method)

Variables a b are the first two common parameters, x is a iterative set of parameters trailing with 0 more arguments:

julia> bar(1,2)
(1,2,())

julia> bar(1,2,3)
(1,2,(3,))

julia> bar(1,2,3,4)
(1,2,(3,4))

julia> bar(1,2,3,4,5,6)
(1,2,(3,4,5,6))

In the example above, x a multiple group bar that are followed to bar.

When a function is called, you can also use ...

julia> x = (3,4)
(3,4)

julia> bar(1,2,x...)
(1,2,(3,4))

In the example above, the values of a plural group are interpoled exactly as defined by the variable parameter function, or they can be called without fully complying with its function definition:

julia> x = (2,3,4)
(2,3,4)

julia> bar(1,x...)
(1,2,(3,4))

julia> x = (1,2,3,4)
(1,2,3,4)

julia> bar(x...)
(1,2,(3,4))

Objects that are interpoled can also be not multigroups:

julia> x = [3,4]
2-element Array{Int64,1}:
 3
 4

julia> bar(1,2,x...)
(1,2,(3,4))

julia> x = [1,2,3,4]
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> bar(x...)
(1,2,(3,4))

The original function can also be a variable function (in most cases, it should be written as a variable parameter function):

baz(a,b) = a + b

julia> args = [1,2]
2-element Int64 Array:
 1
 2

julia> baz(args...)
3

julia> args = [1,2,3]
3-element Int64 Array:
 1
 2
 3

julia> baz(args...)
no method baz(Int64,Int64,Int64)

However, if the number of arguments entered is not correct, the function call will fail.

Optional parameters

Many times, function parameters have default values. F or example, the parseint(num,base) parses a string to a number of progresses. base parameter defaults 10 This scenario can be written as:

function parseint(num, base=10)
    ###
end

At this point, when a function is called, the argument can be one or two. When the second argument is not specified, 10

julia> parseint("12",10)
12

julia> parseint("12",3)
5

julia> parseint("12")
12

Optional parameters are convenient for multi-method definitions with different numbers of parameters (see Method for details).

Keyword parameters

Some functions have a large number of arguments, or have a lot of behavior. I t is difficult to remember how to call such a function. Keyword parameters, allowing parameter names to distinguish between parameters, easy to use and extend these complex interfaces.

For example, plot is used to draw a line. T his function has many options to control the type, width, color, and so on of the line. I f it receives keyword parameters, we can call forms such as plot(x, y, width=2) the line. Such call methods label parameters for easy reading, or pass some parameters in any order.

Use a function of a keyword argument to define it with a part sign in the function signature:

function plot(x, y; style="solid", width=1, color="black")
    ###
end

Additional keyword parameters can be matched with ... as in variable ... functions:

function f(x; y=0, args...)
    ###
end

Inside the f args a collection of (key,value) multiple groups, where key the symbol. Y ou can use a sign to pass the collection when a function is called, f(x, z=1; args...). You can also use a dictionary in this case.

The default value of a keyword parameter is evaluated only from left to right when necessary (when the corresponding keyword parameter is not passed), so the default (keyword parameter) expression can call the keyword argument before it.

The value scope of the default value

The difference between optional and keyword parameters is how their default values are valued. W hen an optional argument is valued, only the arguments before it are within scope; I n contrast, when the default value of the keyword parameter is calculated, all parameters are within scope. For example, define a function:

function f(x, a=b, b=1)
    ###
end

a=b b to b outside the scope of b not the next b However, a and b b keyword parameters, then they b will both be generated in the same scope, a=b points to the next argument b b a=b the expression of the default argument is a b assigned).

The block syntax of the function argument

Passing functions as arguments to other functions is sometimes inconvenient when there are more rows. The following example calls map in a multi-line map

map(x->begin
           if x < 0 && iseven(x)
               return 0
           elseif x == 0
               return 1
           else
               return x
           end
       end,
    [A, B, C])

Julia provides a do to rewrite this code to make it clearer:

map([A, B, C]) do x
    if x < 0 && iseven(x)
        return 0
    elseif x == 0
        return 1
    else
        return x
    end
end

do x of do x creates an anonymous function with argument x and passes it map as the first argument. Similarly, do a,b will create an anonymous function with two parameters, and do declaration () -> .... state that the following is an anonymous function.

How these parameters are initialized depends on the "external" function, where map sets x A B C in turn, and each will call an anonymous function, as it does in the syntax map(func, [A, B, C])

Because syntax calls look like normal blocks of code, this syntax makes it easier to use functions to effectively extend the language. T here are many uses that can be map such as management system state. For example, there is a version of open runs code to ensure that the open file ends up closed:

open("outfile", "w") do io
    write(io, data)
end

It can be implemented by defining:

function open(f::Function, args...)
    io = open(args...)
    try
        f(io)
    finally
        close(io)
    end
end

In contrast map example, the IO here is open("outfile", "w") T he character stream is then passed to open the anonymous function that executes the write; try/finally is described in the control flow.

The use of do block syntax helps you examine documents or implement understanding how parameters of user functions are initialized.