Tracks
/
Julia
Julia
/
Temario
/
Funciones
Fu

Funciones en Julia

2 ejercicios

Acerca de Funciones

El concepto Basics presentó dos formas de definir una función.

La más general, la forma multilínea:

function muladd(x, y, z)
    x * y + z
end

La forma de «asignación», o de «una sola línea», para definiciones cortas:

muladd(x, y, z) = x * y + z

En una tercera forma, aún más corta, se puede crear una función breve de un solo uso sin nombre:

julia> map(x -> 2x, 1:3)
4-element Vector{Int64}:
 2
 4
 6

julia> map((x, y) -> x * y, 1:3, 4:6)
3-element Vector{Int64}:
  4
 10
 18

En este caso, x -> 2x es una «función anónima». Esto equivale a lo que otros lenguajes llaman una «función lambda».

Ten en cuenta que varios argumentos necesitan paréntesis, como en (x, y) -> x * y.

Las funciones anónimas son frecuentes en el código de Julia, sobre todo cuando se combinan con funciones de orden superior como map() y filter().

Argumentos de las funciones

Hasta ahora, en el temario solo hemos visto funciones que tienen un número concreto de argumentos y que exigen que las llamadas a la función los proporcionen todos, en el orden correcto. Eso sería limitante e incómodo, así que hay varias opciones más.

Argumentos opcionales

Como muchos otros lenguajes, Julia permite que las definiciones de funciones especifiquen valores predeterminados para argumentos concretos.

Una llamada a la función puede entonces proporcionar un valor para ese argumento, u omitirlo y confiar en el valor predeterminado.

julia> f(x, y=10) = x * y
f (generic function with 2 methods)

julia> f(2, 3)
6

julia> f(2)
20

Todos los argumentos sin valor predeterminado deben ir antes que cualquier argumento con valor predeterminado, lo que significa que f(x=2, y) no sería válido.

Argumentos de palabra clave

Todos los ejemplos anteriores usan positional arguments, en los que los valores proporcionados en una llamada a la función deben coincidir con el orden de los argumentos correspondientes en la definición de la función.

Como muchos otros lenguajes, Julia también permite keyword arguments. Las llamadas a la función deben especificar el nombre del argumento, pero después se pueden indicar varios argumentos de palabra clave en cualquier orden.

Una característica distintiva de Julia es que los argumentos de palabra clave (si los hay) en la definición de la función deben ir precedidos de un punto y coma ; para separarlos de los argumentos posicionales. Una llamada a la función puede usar ; o , entre el último argumento posicional y el primer argumento de palabra clave.

julia> b(x; y) = x + y
b (generic function with 1 method)

julia> b(2, y=3)
5

# keyword is required when calling
julia> b(2, 3)
ERROR: MethodError: no method matching b(::Int64, ::Int64)
The function `b` exists, but no method is defined for this combination of argument types.

Opcionalmente se pueden especificar valores predeterminados, exactamente igual que con los argumentos posicionales.

Es habitual acabar con una sintaxis como myarg=myarg dentro de una llamada a la función, cuando se ha calculado de antemano una variable con el mismo nombre que el parámetro. En esa situación se permite una sintaxis abreviada:

julia> width = 4.0
4.0

julia> height = √ width
2.0

julia> area(; width, height) = width * height
area (generic function with 1 method)

# repetition
julia> area(; width=width, height=height)
8.0

# shorthand form
julia> area(; width, height)
8.0

Splat y slurp

Estos son los nombres estándar de un aspecto muy útil de la sintaxis de Julia, por si te lo preguntabas. Ambos se refieren al operador ....

Splat

El splatting se usa en las llamadas de funciones para expandir colecciones en los valores individuales que la función necesita.

Puede que sea más fácil demostrarlo que explicarlo:

julia> fxyz(x, y, z) = x * y * z
fxyz (generic function with 1 method)

julia> xyz = [2, 3, 4]
3-element Vector{Int64}:
 2
 3
 4

# Using the vector directly in a function call is invalid
julia> fxyz(xyz)
ERROR: MethodError: no method matching fxyz(::Vector{Int64})
The function `fxyz` exists, but no method is defined for this combination of argument types.

# splatting converts the vector to 3 numbers, used as positional arguments
julia> fxyz(xyz...)
24

Algunas «llamadas a funciones» quedan ocultas por el azúcar sintáctico, así que el splatting también se puede usar de formas menos evidentes.

Por ejemplo, la asignación múltiple usa internamente una función constructora de tuplas:

julia> first, rest... = [1, 2, 3, 4]
4-element Vector{Int64}:
 1
 2
 3
 4

julia> first
1

julia> rest
3-element Vector{Int64}:
 2
 3
 4

Los argumentos de palabra clave también se pueden proporcionar mediante splatting, normalmente usando un named tuple. Un Dict también funciona, pero las claves deben ser símbolos (los strings no funcionan aquí).

# function with 3 keyword arguments
julia> fabc(; a, b, c) = a + b + c
fabc (generic function with 1 method)

# named tuple
julia> abc_nt = (a=2, b=3, c=4)
(a = 2, b = 3, c = 4)

# there are no positional arguments, so need to use ; before kw argument
julia> fabc(;abc_nt...)
9

# Dict
julia> abc_dict = Dict(:a=>2, :b=>3, :c=>4)
Dict{Symbol, Int64} with 3 entries:
  :a => 2
  :b => 3
  :c => 4

julia> fabc(;abc_dict...)
9
Slurp

El slurping se usa en la definición de la función para empaquetar un número arbitrario de valores individuales en una colección.

julia> f_more(i, j, more...) = i + j + sum(more)
f_more (generic function with 1 method)

julia> f_more(1, 3, 5, 7, 9, 11)
36

El nombre del argumento agrupado con slurping (en este caso more) no es relevante. El tipo de esta variable lo elige el compilador, pero en el caso de los argumentos posicionales lo más probable es que sea tuple o algo similar.

Los argumentos de palabra clave también se pueden agrupar con slurping, lo que da un Dict (o algo similar).

julia> f_kwslurp(x, y; switches...) = :mult in keys(switches) ? x * y : x + y
f_kwslurp (generic function with 1 method)

julia> f_kwslurp(5, 6; mult=true)
30

julia> f_kwslurp(5, 6)
11

En la llamada se puede usar cualquier argumento de palabra clave. Es la definición de la función la que decide a qué palabras clave responder y cuáles ignorar.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña

Aprende Funciones

La práctica está bloqueada

Desbloquea 1 ejercicio más para practicar Funciones