Skip to content

Julia Functions

Functions are the basic building blocks of Julia programs. Julia's functions are powerful with various definition styles and advanced features.

Function Definition

Basic Definition

julia
# Standard definition
function greet(name)
    println("Hello, $name!")
end

greet("Julia")  # Hello, Julia!

# With return value
function add(a, b)
    return a + b
end

result = add(3, 5)
println(result)  # 8

# Last expression is automatically returned
function multiply(a, b)
    a * b  # No return needed
end

Short Definition

julia
# Single-line function definition
add(a, b) = a + b
square(x) = x^2

println(add(3, 5))     # 8
println(square(4))     # 16

# More complex single-line function
distance(x, y) = sqrt(x^2 + y^2)
println(distance(3, 4))  # 5.0

Anonymous Functions

julia
# Using -> syntax
f = x -> x^2
println(f(5))  # 25

# Multiple parameters
add = (x, y) -> x + y
println(add(3, 4))  # 7

# Used in higher-order functions
numbers = [1, 2, 3, 4, 5]
squares = map(x -> x^2, numbers)
println(squares)  # [1, 4, 9, 16, 25]

# Using function to define anonymous function
f = function(x, y)
    x + y
end

Parameters

Positional Parameters

julia
function describe(name, age, city)
    println("$name is $age years old and lives in $city")
end

describe("Alice", 30, "Beijing")

Default Parameters

julia
function greet(name, greeting="Hello")
    println("$greeting, $name!")
end

greet("Julia")            # Hello, Julia!
greet("Julia", "Hi")      # Hi, Julia!

# Multiple default parameters
function create_user(name, age=18, active=true)
    return (name=name, age=age, active=active)
end

println(create_user("Bob"))            # (name = "Bob", age = 18, active = true)
println(create_user("Alice", 25))      # (name = "Alice", age = 25, active = true)

Keyword Parameters

Use semicolon ; to separate positional and keyword parameters:

julia
function create_user(name; age=18, city="Unknown")
    return (name=name, age=age, city=city)
end

# Must use keyword names
println(create_user("Alice"))
println(create_user("Bob", age=25))
println(create_user("Charlie", city="Shanghai", age=30))

# Required keyword parameters (no default value)
function connect(; host, port)
    println("Connecting to $host:$port")
end

connect(host="localhost", port=8080)

Variadic Parameters

julia
# Positional variadic parameters
function sum_all(args...)
    total = 0
    for x in args
        total += x
    end
    return total
end

println(sum_all(1, 2, 3))        # 6
println(sum_all(1, 2, 3, 4, 5))  # 15

# Keyword variadic parameters
function print_kwargs(; kwargs...)
    for (key, value) in kwargs
        println("$key = $value")
    end
end

print_kwargs(a=1, b=2, c=3)

# Splatting arguments
args = (1, 2, 3)
println(sum_all(args...))  # 6

kwargs = (a=1, b=2)
print_kwargs(; kwargs...)

Return Values

Single Return Value

julia
function double(x)
    return x * 2
end

Multiple Return Values

julia
# Return tuple
function minmax(a, b)
    if a < b
        return (a, b)
    else
        return (b, a)
    end
end

result = minmax(5, 3)
println(result)  # (3, 5)

# Destructure return value
min_val, max_val = minmax(5, 3)
println("min: $min_val, max: $max_val")

# Return named tuple
function analyze(data)
    return (
        min = minimum(data),
        max = maximum(data),
        avg = sum(data) / length(data)
    )
end

result = analyze([1, 2, 3, 4, 5])
println(result.avg)  # 3.0

No Return Value

julia
function print_hello()
    println("Hello!")
    # Implicitly returns nothing
end

result = print_hello()
println(result)  # nothing

Type Annotations

Parameter Types

julia
function add(a::Int, b::Int)
    return a + b
end

println(add(3, 5))    # 8
# add(3.0, 5.0)       # Error! Type mismatch

# Abstract types
function add_numbers(a::Number, b::Number)
    return a + b
end

println(add_numbers(3, 5.0))  # 8.0

Return Types

julia
function divide(a, b)::Float64
    return a / b
end

result = divide(10, 3)
println(typeof(result))  # Float64

Parametric Types

julia
function first_element(arr::Vector{T}) where T
    return arr[1]::T
end

println(first_element([1, 2, 3]))      # 1
println(first_element(["a", "b"]))     # "a"

Multiple Dispatch

One of Julia's core features is multiple dispatch: selecting methods based on types of all arguments.

julia
# Define multiple methods
describe(x::Int) = "Integer: $x"
describe(x::Float64) = "Float: $x"
describe(x::String) = "String: $x"
describe(x) = "Unknown type: $x"

println(describe(42))       # Integer: 42
println(describe(3.14))     # Float: 3.14
println(describe("hello"))  # String: hello
println(describe([1,2,3]))  # Unknown type: [1, 2, 3]

# Multi-argument dispatch
multiply(a::Int, b::Int) = "Two integers: $(a * b)"
multiply(a::Float64, b::Float64) = "Two floats: $(a * b)"
multiply(a::Int, b::Float64) = "Mixed types: $(a * b)"

println(multiply(3, 4))       # Two integers: 12
println(multiply(3.0, 4.0))   # Two floats: 12.0
println(multiply(3, 4.0))     # Mixed types: 12.0

Viewing Methods

julia
# View all methods of a function
println(methods(describe))

# View method for specific types
println(@which describe(42))

Higher-Order Functions

Functions as Arguments

julia
function apply_twice(f, x)
    return f(f(x))
end

println(apply_twice(x -> x + 1, 5))  # 7
println(apply_twice(x -> x * 2, 3))  # 12

Functions as Return Values

julia
function make_multiplier(n)
    return x -> x * n
end

double = make_multiplier(2)
triple = make_multiplier(3)

println(double(5))  # 10
println(triple(5))  # 15

Common Higher-Order Functions

julia
arr = [1, 2, 3, 4, 5]

# map - mapping
println(map(x -> x^2, arr))  # [1, 4, 9, 16, 25]

# filter - filtering
println(filter(x -> x > 2, arr))  # [3, 4, 5]

# reduce - reduction
println(reduce(+, arr))  # 15

# foreach - iteration (no return value)
foreach(println, arr)

# any / all - condition checks
println(any(x -> x > 3, arr))  # true
println(all(x -> x > 0, arr))  # true

do Syntax

For passing multi-line anonymous functions:

julia
# Using do block
result = map([1, 2, 3]) do x
    y = x^2
    y + 1
end
println(result)  # [2, 5, 10]

# Equivalent to
result = map(x -> begin
    y = x^2
    y + 1
end, [1, 2, 3])

# Common in file operations
open("test.txt", "w") do f
    write(f, "Hello, Julia!")
end

Closures

Functions can capture external variables:

julia
function make_counter()
    count = 0
    return function()
        count += 1
        return count
    end
end

counter = make_counter()
println(counter())  # 1
println(counter())  # 2
println(counter())  # 3

# Another independent counter
counter2 = make_counter()
println(counter2())  # 1

Function Composition

julia
# Compose functions using ∘
f = sqrt  abs
println(f(-16))  # 4.0 (abs first, then sqrt)

# Chain composition
g = uppercase  strip  string
println(g(42))  # "42"

# Pipe operator
result = -16 |> abs |> sqrt
println(result)  # 4.0

Recursion

julia
# Factorial
function factorial(n)
    if n <= 1
        return 1
    else
        return n * factorial(n - 1)
    end
end

println(factorial(5))  # 120

# Fibonacci (with memoization)
function fib(n, memo=Dict{Int,Int}())
    if n <= 2
        return 1
    end
    if haskey(memo, n)
        return memo[n]
    end
    result = fib(n-1, memo) + fib(n-2, memo)
    memo[n] = result
    return result
end

println(fib(50))  # 12586269025

Built-in Function Operations

julia
# Function info
println(methods(+))   # View all + methods

# Method lookup
@which 1 + 2         # View specific method used

# Parameter info
# Use ? in REPL to view function documentation

Docstrings

julia
"""
    add(a, b)

Calculate the sum of two numbers.

# Arguments
- `a`: First number
- `b`: Second number

# Returns
Returns the sum of a and b.

# Examples
```julia
julia> add(2, 3)
5

""" function add(a, b) return a + b end

Use ? add in REPL to view documentation


## Next Steps

After learning functions, continue with:
- [Control Flow](julia-control-flow) - Conditions and loops
- [Metaprogramming](julia-metaprogramming) - Macros and code generation
- [Data Types](julia-data-types) - Types in functions

Content is for learning and research only.