Easy Tutorial
❮ Julia Tuples Julia Strings ❯

Julia Functions

A function is a group of statements that together perform a task.

In Julia, a function is an object that maps a tuple of argument values to a return value.

Functions in Julia are defined using the function keyword, with the basic syntax being:

function functionname(args)
   expression
   expression
   expression
   ...
   expression
end

By default, the value returned by a function is the value of the last evaluated expression, so we do not see a return statement above. However, if the return keyword is used, the function will return immediately.

Example

julia> function f(x,y)
         x + y
       end
f (generic function with 1 method)
julia> f(2,3)
5

julia> function bills(money)
       if money < 0
         return false
       else
         return true
       end
     end
bills (generic function with 1 method)

julia> bills(50)
true

julia> bills(-50)
false

If a function needs to return multiple values, a tuple can be used:

Example

julia> function mul(x,y)
               x+y, x*y
             end
mul (generic function with 1 method)

julia> mul(5, 10)
(15, 50)

When a function contains only one expression, you can omit the function keyword, setting the function name and parameters on the left side of the equals sign and the expression on the right side, similar to an assignment:

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

Without parentheses, the expression f refers to the function object and can be passed around like any value:

julia> g = f;
julia> g(2,3)
5

Example

julia> f(a) = a * a
f (generic function with 1 method)

julia> f(5)
25

julia> func(x, y) = sqrt(x^2 + y^2)
func (generic function with 1 method)

julia> func(5, 4)
6.4031242374328485

Like variable names, Unicode characters can also be used as function names:

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

julia> ∑(2, 3)
5

Return Type

We can specify the return type of a function using the :: operator.

Example

julia> function g(x, y)::Int8
         return x * y
       end;

julia> typeof(g(1, 2))
Int8

The above function example will ignore the types of x and y and return a value of type Int8.

Optional Parameters

In functions, we can set default values for parameters, so that if the parameter is not provided, the default value is used for computation:

The following example defines a function pos with three parameters, where the parameter cz has a default value of 0. This parameter can be omitted when calling the function:

Example

julia> function pos(ax, by, cz=0)
         println("$ax, $by, $cz")
       end
pos (generic function with 2 methods)

julia> pos(10, 30)
10, 30, 0

julia> pos(10, 30, 50)
10, 30, 50

Keyword Arguments

Sometimes, functions we define require a large number of parameters, which can be cumbersome to call because we might forget the order of the parameters. For example:

function foo(a, b, c, d, e, f)
...
end

We might forget the order of the parameters, leading to situations like:

foo("25", -5.6987, "hello", 56, good, 'ABC')
or
foo("hello", 56, "25", -5.6987, 'ABC', good)

This can be very confusing.

Julia's keyword arguments allow parameters to be identified by name rather than just by position, making these complex functions easier to use and extend.

To mark parameters with keywords, a semicolon ; must be used after the unmarked parameters in the function, followed by one or more key-value pairs key=value, as shown below:

Example

function foo(a; b=1, c=2)
...
end
julia> function foo(a, b; c = 10, d = "hi")
       println("a is $a")
       println("b is $b")
       return "c => $c, d => $d"
       end
foo (generic function with 1 method)

julia> foo(100, 20)
a is 100
b is 20
"c => 10, d => hi"

julia> foo("Hello", "tutorialpro", c=pi, d=22//7)
a is Hello
b is tutorialpro
"c => π, d => 22//7"

With keyword arguments, the position of the arguments becomes less important. We can call the function like this:

Example

julia> foo(c=pi, d=22/7, "Hello", "tutorialpro")
a is Hello
b is tutorialpro
"c => π, d => 3.142857142857143"

Anonymous Functions

An anonymous function is a function without a name.

Anonymous functions are declared dynamically during program execution and are identical to standard functions except for the absence of a name.

In Julia, anonymous functions can be used in many places, such as with map() and list comprehensions.

Using anonymous functions makes our code more concise.

The syntax for anonymous functions uses the -> symbol.

Example

julia> x -> x^2 + 2x - 1
#1 (generic function with 1 method)

julia> function (x)
       x^2 + 2x - 1
       end
#3 (generic function with 1 method)

The above example creates a function that takes a single argument x and returns the polynomial x^2 + 2x - 1.

The primary use of anonymous functions is to pass them to functions that take other functions as arguments. A classic example is map(), which applies a function to each element of an array and returns a new array with the resulting values:

Example

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

If the transformation function passed as the first argument to map() already exists, using its name directly is fine. However, if the function to be used is not yet defined, using an anonymous function is more convenient:

Example

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

Anonymous functions that take multiple arguments can be written as (x, y, z) -> 2x + y - z, and those without arguments as () -> 3. This syntax for no-argument functions may seem odd, but it is necessary for delayed evaluation. This usage wraps a block of code into a no-argument function, which can then be called as f.

For example, consider a call to get:

Example

get(dict, key) do
    # default value calculated here
    time()
end

The above code is equivalent to calling get with an anonymous function that contains the code between do and end, as shown below:

get(() -> time(), dict, key)

Here, the call to time is delayed by wrapping it in a no-argument anonymous function. This anonymous function is called only when the requested key is missing from dict.


Function Nesting and Recursion

In Julia, functions can be nested.

The following example nests an add1 function within an add function:

Example

julia> function add(x)
       Y = x * 2
       function add1(Y)
       Y += 1
       end
       add1(Y)
       end
add (generic function with 1 method)

julia> d = 10
10

julia> add(d)
21

Similarly, functions in Julia can be recursive.

Recursion refers to a method where a function calls itself in its definition.

>

For example:

We use the ternary operator to test recursion, which operates on three operands expr ? a : b. If expr is true, the result is the evaluation of a; otherwise, it is the evaluation of b.

Example

julia> sum(x) = x > 1 ? sum(x-1) + x : x
sum (generic function with 1 method)

julia> sum(10)
55

The examples above are used to calculate the sum of all numbers up to and including a certain integer. In this recursion, there is a base case where the value is returned when x is 1.

The most famous example of recursion is calculating the nth Fibonacci number, which refers to the sequence 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368........

Starting from the 3rd term, each term in this sequence is equal to the sum of the two preceding terms.

Example

julia> fib(x) = x < 2 ? x : fib(x-1) + fib(x-2)
fib (generic function with 1 method)

julia> fib(10)
55

julia> fib(20)
6765

Map

The definition format for Map is as follows:

map(func, coll)

Here, func is a function that is applied to each element of the collection coll. Map typically includes anonymous functions and returns a new collection.

Example

julia> map(A -> A^3 + 3A - 3, [10,3,-2])
3-element Array{Int64,1}:
 1027
  33
 -17

Filter

The definition format for Filter is as follows:

filter(function, collection)

The filter function returns a copy of the collection, removing elements that result in false when the function is called.

Example

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

julia> filter(x -> x % 2 == 0, array)
1-element Array{Int64,1}:
 2
❮ Julia Tuples Julia Strings ❯