Funciones y estructuras en Mojo

Andres Felipe Ocampo
5 min readSep 2, 2024

--

Funciones

Mojo admite dos tipos de funciones, las funciones def y fn puedes utilizar cualquiera de las declaraciones con cualquier función, incluida la función principal, pero tienen diferentes comportamientos.

Las funciones def y fn tienen buenos casos de uso y no considero que ninguna sea mejor que la otra decidir cuál utilizar es una cuestión de gusto personal en cuanto a qué estilo se adapta mejor a una tarea determinada. Las funciones def proporcionan el mismo dinamismo y flexibilidad que una función def de Python.

def addNumbers(a,b):
c = a + b
return c


print(addNumbers(2,3))

def addNewNumber(a,b,c):
d = a + b - c
return d

print(addNewNumber(1,2,3))

Por ejemplo, tenemos dos funciones def para sumar números dentro de esta función proporcionaré dos argumentos y luego utilizaré una tercera variable para asignar la suma de ambas variables, al final devolveré la tercera variable al final ejecutamos la funcion print(), llamaré a addNumbers() y proporcionaré dos valores.

Esta era una forma más pitónica de declarar las funciones. También podemos especificar el tipo de argumento o el tipo de retorno y la mutabilidad de la variable por daros un ejemplo.

def saludaMojo(name: String) -> String:
var saluda = "Hola" + name + "!"
return saluda

print(saludaMojo(" Andres"))

Especificar el tipo de argumento y el tipo de retorno definimos una nueva función y la nombraré como saludo y dentro de los paréntesis daré el nombre de la variable y el tipo además especifico el tipo de retorno, muy parecido a Swift y esta función devolverá un String.

fn addNumberFn(a: Int8, b: Int8) -> Int8:
var c: Int8 = a + b
return c

print(addNumberFn(2,3))

Esta otra forma de declarar la fuciones mas de Mojo, se proporciona una verificación de tipo estricta y seguridad de memoria adicional por ejemplo, podemos definir una fn addnumbersFn(), y dentro de los paréntesis lo que haremos es especificar dos argumentos, por lo que el primero será de tipo Int8 y el tipo de retorno también será Int8 declararemos una tercera variable del tipo Int8, y luego agregaremos las dos variables que provienen de los argumentos del método, el tipo se inferirá desde aquí al final devolveremos c, luego dentro de la función print llamaré. En lo que respecta a un llamador de función, def y la función fn son intercambiables. No hay nada que una función def pueda hacer que una función fn no pueda, y viceversa la diferencia es que, en comparación con una función def, la función fn es más estricta internamente Por lo tanto, tenemos que proporcionar explícitamente los tipos de argumentos y los tipos de retorno en las funciones fn.

Estructuras (struct)

En los modelos, Mojo ofrecen una forma poderosa de agrupar datos y funciones relacionadas en una sola unidad, esto facilita la organización del código y mejora la reutilización del código, exploremos el concepto de struct usando un ejemplo de animal.

struct Animal:
var edad: Int
var especie: String
var sonido: String

fn __init__(inout self, edad: Int, especie: String, sonido: String):
self.edad = edad
self.especie = especie
self.sonido = sonido

fn printProps(self):
print(self.edad)
print(self.especie)
print(self.sonido)


var perro = Animal(10, "Perro", "wolf")
var gato = Animal(8, "Gato", "Miauu")

perro.printProps()
gato.printProps()

Imaginemos que estamos creando un programa para administrar información sobre diferentes animales podrías definir una estructura llamada Animal con las siguientes propiedades.

En primer lugar, usaremos la palabra reservada struct y el nombre de la estructura esta estructura es similar a las clases en diferentes lenguajes de programación com por ejemplo Swift o Objective C de iOS, la primera propiedad será la edad debe ser Int, la segunda propiedad es especie del tipo String, la tercera propiedad de la estructura animal es sonido, del tipo String, después de crear la estructura, como definimos el constructor en otros lenguajes de programación, también debemos hacer lo mismo para definir un constructor, usaremos una función __ ini__(), después de usar la palabra reservada fn __init__(), para especificar que se trata de un constructor, y dentro de este constructor, usaremos inout(es una convención de argumentos que se declara selfcomo una referencia mutable), todo lo que necesitas saber ahora es que selfdebe ser el primer argumento, luego se declaran el resto de variables para que el constructor inicialice todas las propiedades de la estructura.

El método__init__() es uno de los muchos métodos especiales (también conocidos como "métodos dunder" porque tienen puntuaciones dobles inferiores ) con nombres predeterminados.

Establecemos las variables referenciadas en la structura y la igualamos a los argumentos de la fn __init__(), para eso usaremos la palabra reservada self como en otros lenguajes de programación, y se refiere al objeto de esta clase.

Crearemos otra función para imprimir propiedades, para imprimir las propiedades, y pasaré la palabra clave self dentro de esta función, luego imprimiré diferentes propiedades usando la palabra clave self.

En pocas palabras, struct se usa para agrupar datos y funciones relacionadas en una sola unidad y hace que sea más fácil organizar tu código y mejorar la reutilización del código.

Hay palabras clave diferentes que se pueden usar con argumentos de función para jugar con la mutabilidad e inmutabilidad de las variables primero que nada, veamos un ejemplo de inout.

fn add(inout a: Int, inout b: Int) -> Int:
a = 10
b = 5
return a + b


fn main():
var a = 4
var b = 5
print(add(a,b))


main()

En la función main(), definiremos dos variables a y bde tipos enteros, digamos que a = 4 y b = 5, llamamos al método add y sumaremos a y b en este escenario usaremos inout, luego definiremos los argumentos de la función, el primero es a: Int y el segundo es b: Int, dentro de esta función cambiaremos o mutaremos los valores de a y b -> valores diferentes, por ejemplo, a = 10 y b = 5 y luego devolveremos a + b, pero dentro de la función add estamos modificando o mutando su valor, estamos mutando los valores de a y b, como puedes ver, el resultado es 15, en el caso de inout, los valores dentro de esta función son visibles fuera de esta función, lo que significa que podemos cambiar la mutabilidad de estos valores dentro de esta función, esto en mi opnión se usa muy pocas veces, pero es buenos conocerlo.

--

--